OSDN Git Service

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