OSDN Git Service

am 550f1d4e: Merge "Delete overscan setting by both unique id and name." into cw...
[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.graphics.Rect;
20 import android.os.Environment;
21 import android.util.AtomicFile;
22 import android.util.Slog;
23 import android.util.Xml;
24 import com.android.internal.util.FastXmlSerializer;
25 import com.android.internal.util.XmlUtils;
26 import org.xmlpull.v1.XmlPullParser;
27 import org.xmlpull.v1.XmlPullParserException;
28 import org.xmlpull.v1.XmlSerializer;
29
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.FileNotFoundException;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.nio.charset.StandardCharsets;
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 AtomicFile mFile;
45     private final HashMap<String, Entry> mEntries = new HashMap<String, Entry>();
46
47     public static class Entry {
48         public final String name;
49         public int overscanLeft;
50         public int overscanTop;
51         public int overscanRight;
52         public int overscanBottom;
53
54         public Entry(String _name) {
55             name = _name;
56         }
57     }
58
59     public DisplaySettings() {
60         File dataDir = Environment.getDataDirectory();
61         File systemDir = new File(dataDir, "system");
62         mFile = new AtomicFile(new File(systemDir, "display_settings.xml"));
63     }
64
65     public void getOverscanLocked(String name, String uniqueId, Rect outRect) {
66         // Try to get the entry with the unique if possible.
67         // Else, fall back on the display name.
68         Entry entry;
69         if (uniqueId == null || (entry = mEntries.get(uniqueId)) == null) {
70             entry = mEntries.get(name);
71         }
72         if (entry != null) {
73             outRect.left = entry.overscanLeft;
74             outRect.top = entry.overscanTop;
75             outRect.right = entry.overscanRight;
76             outRect.bottom = entry.overscanBottom;
77         } else {
78             outRect.set(0, 0, 0, 0);
79         }
80     }
81
82     public void setOverscanLocked(String uniqueId, String name, int left, int top, int right,
83             int bottom) {
84         if (left == 0 && top == 0 && right == 0 && bottom == 0) {
85             // Right now all we are storing is overscan; if there is no overscan,
86             // we have no need for the entry.
87             mEntries.remove(uniqueId);
88             // Legacy name might have been in used, so we need to clear it.
89             mEntries.remove(name);
90             return;
91         }
92         Entry entry = mEntries.get(uniqueId);
93         if (entry == null) {
94             entry = new Entry(uniqueId);
95             mEntries.put(uniqueId, entry);
96         }
97         entry.overscanLeft = left;
98         entry.overscanTop = top;
99         entry.overscanRight = right;
100         entry.overscanBottom = bottom;
101     }
102
103     public void readSettingsLocked() {
104         FileInputStream stream;
105         try {
106             stream = mFile.openRead();
107         } catch (FileNotFoundException e) {
108             Slog.i(TAG, "No existing display settings " + mFile.getBaseFile()
109                     + "; starting empty");
110             return;
111         }
112         boolean success = false;
113         try {
114             XmlPullParser parser = Xml.newPullParser();
115             parser.setInput(stream, StandardCharsets.UTF_8.name());
116             int type;
117             while ((type = parser.next()) != XmlPullParser.START_TAG
118                     && type != XmlPullParser.END_DOCUMENT) {
119                 // Do nothing.
120             }
121
122             if (type != XmlPullParser.START_TAG) {
123                 throw new IllegalStateException("no start tag found");
124             }
125
126             int outerDepth = parser.getDepth();
127             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
128                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
129                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
130                     continue;
131                 }
132
133                 String tagName = parser.getName();
134                 if (tagName.equals("display")) {
135                     readDisplay(parser);
136                 } else {
137                     Slog.w(TAG, "Unknown element under <display-settings>: "
138                             + parser.getName());
139                     XmlUtils.skipCurrentTag(parser);
140                 }
141             }
142             success = true;
143         } catch (IllegalStateException e) {
144             Slog.w(TAG, "Failed parsing " + e);
145         } catch (NullPointerException e) {
146             Slog.w(TAG, "Failed parsing " + e);
147         } catch (NumberFormatException e) {
148             Slog.w(TAG, "Failed parsing " + e);
149         } catch (XmlPullParserException e) {
150             Slog.w(TAG, "Failed parsing " + e);
151         } catch (IOException e) {
152             Slog.w(TAG, "Failed parsing " + e);
153         } catch (IndexOutOfBoundsException e) {
154             Slog.w(TAG, "Failed parsing " + e);
155         } finally {
156             if (!success) {
157                 mEntries.clear();
158             }
159             try {
160                 stream.close();
161             } catch (IOException e) {
162             }
163         }
164     }
165
166     private int getIntAttribute(XmlPullParser parser, String name) {
167         try {
168             String str = parser.getAttributeValue(null, name);
169             return str != null ? Integer.parseInt(str) : 0;
170         } catch (NumberFormatException e) {
171             return 0;
172         }
173     }
174
175     private void readDisplay(XmlPullParser parser) throws NumberFormatException,
176             XmlPullParserException, IOException {
177         String name = parser.getAttributeValue(null, "name");
178         if (name != null) {
179             Entry entry = new Entry(name);
180             entry.overscanLeft = getIntAttribute(parser, "overscanLeft");
181             entry.overscanTop = getIntAttribute(parser, "overscanTop");
182             entry.overscanRight = getIntAttribute(parser, "overscanRight");
183             entry.overscanBottom = getIntAttribute(parser, "overscanBottom");
184             mEntries.put(name, entry);
185         }
186         XmlUtils.skipCurrentTag(parser);
187     }
188
189     public void writeSettingsLocked() {
190         FileOutputStream stream;
191         try {
192             stream = mFile.startWrite();
193         } catch (IOException e) {
194             Slog.w(TAG, "Failed to write display settings: " + e);
195             return;
196         }
197
198         try {
199             XmlSerializer out = new FastXmlSerializer();
200             out.setOutput(stream, StandardCharsets.UTF_8.name());
201             out.startDocument(null, true);
202             out.startTag(null, "display-settings");
203
204             for (Entry entry : mEntries.values()) {
205                 out.startTag(null, "display");
206                 out.attribute(null, "name", entry.name);
207                 if (entry.overscanLeft != 0) {
208                     out.attribute(null, "overscanLeft", Integer.toString(entry.overscanLeft));
209                 }
210                 if (entry.overscanTop != 0) {
211                     out.attribute(null, "overscanTop", Integer.toString(entry.overscanTop));
212                 }
213                 if (entry.overscanRight != 0) {
214                     out.attribute(null, "overscanRight", Integer.toString(entry.overscanRight));
215                 }
216                 if (entry.overscanBottom != 0) {
217                     out.attribute(null, "overscanBottom", Integer.toString(entry.overscanBottom));
218                 }
219                 out.endTag(null, "display");
220             }
221
222             out.endTag(null, "display-settings");
223             out.endDocument();
224             mFile.finishWrite(stream);
225         } catch (IOException e) {
226             Slog.w(TAG, "Failed to write display settings, restoring backup.", e);
227             mFile.failWrite(stream);
228         }
229     }
230 }