1c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn/* 2c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * Copyright (C) 2013 The Android Open Source Project 3c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * 4c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * you may not use this file except in compliance with the License. 6c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * You may obtain a copy of the License at 7c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * 8c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * 10c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * Unless required by applicable law or agreed to in writing, software 11c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * See the License for the specific language governing permissions and 14c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * limitations under the License. 15c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn */ 16c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 17c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornpackage com.android.server.wm; 18c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 19c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.content.Context; 20c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.graphics.Rect; 21c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.os.Environment; 22c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.util.AtomicFile; 23c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.util.Slog; 24c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.util.Xml; 25c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport com.android.internal.util.FastXmlSerializer; 26c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport com.android.internal.util.XmlUtils; 27c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport org.xmlpull.v1.XmlPullParser; 28c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport org.xmlpull.v1.XmlPullParserException; 29c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport org.xmlpull.v1.XmlSerializer; 30c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 31c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport java.io.File; 32c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport java.io.FileInputStream; 33c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport java.io.FileNotFoundException; 34c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport java.io.FileOutputStream; 35c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport java.io.IOException; 36c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport java.util.HashMap; 37c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 38c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn/** 39c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn * Current persistent settings about a display 40c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn */ 41c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornpublic class DisplaySettings { 42c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn private static final String TAG = WindowManagerService.TAG; 43c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 44c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn private final Context mContext; 45c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn private final AtomicFile mFile; 46c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn private final HashMap<String, Entry> mEntries = new HashMap<String, Entry>(); 47c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 48c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn public static class Entry { 49c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn public final String name; 50c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn public int overscanLeft; 51c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn public int overscanTop; 52c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn public int overscanRight; 53c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn public int overscanBottom; 54c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 55c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn public Entry(String _name) { 56c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn name = _name; 57c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 58c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 59c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 60c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn public DisplaySettings(Context context) { 61c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn mContext = context; 62c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn File dataDir = Environment.getDataDirectory(); 63c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn File systemDir = new File(dataDir, "system"); 64c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn mFile = new AtomicFile(new File(systemDir, "display_settings.xml")); 65c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 66c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 67c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn public void getOverscanLocked(String name, Rect outRect) { 68c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Entry entry = mEntries.get(name); 69c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn if (entry != null) { 70c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn outRect.left = entry.overscanLeft; 71c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn outRect.top = entry.overscanTop; 72c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn outRect.right = entry.overscanRight; 73c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn outRect.bottom = entry.overscanBottom; 74c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } else { 75c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn outRect.set(0, 0, 0, 0); 76c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 77c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 78c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 79c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn public void setOverscanLocked(String name, int left, int top, int right, int bottom) { 80c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn if (left == 0 && top == 0 && right == 0 && bottom == 0) { 81c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn // Right now all we are storing is overscan; if there is no overscan, 82c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn // we have no need for the entry. 83c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn mEntries.remove(name); 84c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn return; 85c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 86c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Entry entry = mEntries.get(name); 87c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn if (entry == null) { 88c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn entry = new Entry(name); 89c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn mEntries.put(name, entry); 90c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 91c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn entry.overscanLeft = left; 92c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn entry.overscanTop = top; 93c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn entry.overscanRight = right; 94c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn entry.overscanBottom = bottom; 95c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 96c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 97c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn public void readSettingsLocked() { 98c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn FileInputStream stream; 99c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn try { 100c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn stream = mFile.openRead(); 101c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } catch (FileNotFoundException e) { 102c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Slog.i(TAG, "No existing display settings " + mFile.getBaseFile() 103c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn + "; starting empty"); 104c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn return; 105c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 106c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn boolean success = false; 107c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn try { 108c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn XmlPullParser parser = Xml.newPullParser(); 109c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn parser.setInput(stream, null); 110c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn int type; 111c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn while ((type = parser.next()) != XmlPullParser.START_TAG 112c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn && type != XmlPullParser.END_DOCUMENT) { 113c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn ; 114c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 115c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 116c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn if (type != XmlPullParser.START_TAG) { 117c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn throw new IllegalStateException("no start tag found"); 118c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 119c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 120c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn int outerDepth = parser.getDepth(); 121c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 122c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 123c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 124c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn continue; 125c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 126c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 127c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn String tagName = parser.getName(); 128c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn if (tagName.equals("display")) { 129c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn readDisplay(parser); 130c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } else { 131c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Slog.w(TAG, "Unknown element under <display-settings>: " 132c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn + parser.getName()); 133c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn XmlUtils.skipCurrentTag(parser); 134c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 135c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 136c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn success = true; 137c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } catch (IllegalStateException e) { 138c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 139c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } catch (NullPointerException e) { 140c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 141c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } catch (NumberFormatException e) { 142c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 143c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } catch (XmlPullParserException e) { 144c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 145c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } catch (IOException e) { 146c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 147c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } catch (IndexOutOfBoundsException e) { 148c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 149c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } finally { 150c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn if (!success) { 151c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn mEntries.clear(); 152c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 153c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn try { 154c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn stream.close(); 155c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } catch (IOException e) { 156c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 157c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 158c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 159c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 160c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn private int getIntAttribute(XmlPullParser parser, String name) { 161c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn try { 162c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn String str = parser.getAttributeValue(null, name); 163c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn return str != null ? Integer.parseInt(str) : 0; 164c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } catch (NumberFormatException e) { 165c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn return 0; 166c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 167c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 168c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 169c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn private void readDisplay(XmlPullParser parser) throws NumberFormatException, 170c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn XmlPullParserException, IOException { 171c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn String name = parser.getAttributeValue(null, "name"); 172c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn if (name != null) { 173c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Entry entry = new Entry(name); 174c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn entry.overscanLeft = getIntAttribute(parser, "overscanLeft"); 175c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn entry.overscanTop = getIntAttribute(parser, "overscanTop"); 176c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn entry.overscanRight = getIntAttribute(parser, "overscanRight"); 177c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn entry.overscanBottom = getIntAttribute(parser, "overscanBottom"); 178c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn mEntries.put(name, entry); 179c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 180c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn XmlUtils.skipCurrentTag(parser); 181c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 182c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 183c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn public void writeSettingsLocked() { 184c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn FileOutputStream stream; 185c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn try { 186c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn stream = mFile.startWrite(); 187c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } catch (IOException e) { 188c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Slog.w(TAG, "Failed to write display settings: " + e); 189c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn return; 190c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 191c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 192c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn try { 193c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn XmlSerializer out = new FastXmlSerializer(); 194c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn out.setOutput(stream, "utf-8"); 195c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn out.startDocument(null, true); 196c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn out.startTag(null, "display-settings"); 197c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 198c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn for (Entry entry : mEntries.values()) { 199c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn out.startTag(null, "display"); 200c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn out.attribute(null, "name", entry.name); 201c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn if (entry.overscanLeft != 0) { 202c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn out.attribute(null, "overscanLeft", Integer.toString(entry.overscanLeft)); 203c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 204c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn if (entry.overscanTop != 0) { 205c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn out.attribute(null, "overscanTop", Integer.toString(entry.overscanTop)); 206c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 207c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn if (entry.overscanRight != 0) { 208c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn out.attribute(null, "overscanRight", Integer.toString(entry.overscanRight)); 209c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 210c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn if (entry.overscanBottom != 0) { 211c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn out.attribute(null, "overscanBottom", Integer.toString(entry.overscanBottom)); 212c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 213c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn out.endTag(null, "display"); 214c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 215c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn 216c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn out.endTag(null, "display-settings"); 217c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn out.endDocument(); 218c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn mFile.finishWrite(stream); 219c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } catch (IOException e) { 220c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn Slog.w(TAG, "Failed to write display settings, restoring backup.", e); 221c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn mFile.failWrite(stream); 222c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 223c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn } 224c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn} 225