• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.ethernet;
18 
19 import static com.android.net.module.util.DeviceConfigUtils.TETHERING_MODULE_NAME;
20 
21 import android.annotation.Nullable;
22 import android.content.ApexEnvironment;
23 import android.net.IpConfiguration;
24 import android.os.Environment;
25 import android.util.ArrayMap;
26 import android.util.AtomicFile;
27 import android.util.Log;
28 
29 import com.android.internal.annotations.VisibleForTesting;
30 import com.android.server.net.IpConfigStore;
31 
32 import java.io.File;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 
36 /**
37  * This class provides an API to store and manage Ethernet network configuration.
38  */
39 public class EthernetConfigStore {
40     private static final String TAG = EthernetConfigStore.class.getSimpleName();
41     private static final String CONFIG_FILE = "ipconfig.txt";
42     private static final String FILE_PATH = "/misc/ethernet/";
43     private static final String LEGACY_IP_CONFIG_FILE_PATH = Environment.getDataDirectory()
44             + FILE_PATH;
45     private static final String APEX_IP_CONFIG_FILE_PATH = ApexEnvironment.getApexEnvironment(
46             TETHERING_MODULE_NAME).getDeviceProtectedDataDir() + FILE_PATH;
47 
48     private IpConfigStore mStore = new IpConfigStore();
49     private final ArrayMap<String, IpConfiguration> mIpConfigurations;
50     private IpConfiguration mIpConfigurationForDefaultInterface;
51     private final Object mSync = new Object();
52 
EthernetConfigStore()53     public EthernetConfigStore() {
54         mIpConfigurations = new ArrayMap<>(0);
55     }
56 
doesConfigFileExist(final String filepath)57     private static boolean doesConfigFileExist(final String filepath) {
58         return new File(filepath).exists();
59     }
60 
writeLegacyIpConfigToApexPath(final String newFilePath, final String oldFilePath, final String filename)61     private void writeLegacyIpConfigToApexPath(final String newFilePath, final String oldFilePath,
62             final String filename) {
63         final File directory = new File(newFilePath);
64         if (!directory.exists()) {
65             directory.mkdirs();
66         }
67 
68         // Write the legacy IP config to the apex file path.
69         FileOutputStream fos = null;
70         final AtomicFile dst = new AtomicFile(new File(newFilePath + filename));
71         final AtomicFile src = new AtomicFile(new File(oldFilePath + filename));
72         try {
73             final byte[] raw = src.readFully();
74             if (raw.length > 0) {
75                 fos = dst.startWrite();
76                 fos.write(raw);
77                 fos.flush();
78                 dst.finishWrite(fos);
79             }
80         } catch (IOException e) {
81             Log.e(TAG, "Fail to sync the legacy IP config to the apex file path.");
82             dst.failWrite(fos);
83         }
84     }
85 
read()86     public void read() {
87         read(APEX_IP_CONFIG_FILE_PATH, LEGACY_IP_CONFIG_FILE_PATH, CONFIG_FILE);
88     }
89 
90     @VisibleForTesting
read(final String newFilePath, final String oldFilePath, final String filename)91     void read(final String newFilePath, final String oldFilePath, final String filename) {
92         synchronized (mSync) {
93             // Attempt to read the IP configuration from apex file path first.
94             if (doesConfigFileExist(newFilePath + filename)) {
95                 loadConfigFileLocked(newFilePath + filename);
96                 return;
97             }
98 
99             // If the config file doesn't exist in the apex file path, attempt to read it from
100             // the legacy file path, if config file exists, write the legacy IP configuration to
101             // apex config file path, this should just happen on the first boot. New or updated
102             // config entries are only written to the apex config file later.
103             if (!doesConfigFileExist(oldFilePath + filename)) return;
104             loadConfigFileLocked(oldFilePath + filename);
105             writeLegacyIpConfigToApexPath(newFilePath, oldFilePath, filename);
106         }
107     }
108 
loadConfigFileLocked(final String filepath)109     private void loadConfigFileLocked(final String filepath) {
110         final ArrayMap<String, IpConfiguration> configs =
111                 IpConfigStore.readIpConfigurations(filepath);
112         mIpConfigurations.putAll(configs);
113     }
114 
write(String iface, IpConfiguration config)115     public void write(String iface, IpConfiguration config) {
116         write(iface, config, APEX_IP_CONFIG_FILE_PATH + CONFIG_FILE);
117     }
118 
119     @VisibleForTesting
write(String iface, IpConfiguration config, String filepath)120     void write(String iface, IpConfiguration config, String filepath) {
121         boolean modified;
122 
123         synchronized (mSync) {
124             if (config == null) {
125                 modified = mIpConfigurations.remove(iface) != null;
126             } else {
127                 IpConfiguration oldConfig = mIpConfigurations.put(iface, config);
128                 modified = !config.equals(oldConfig);
129             }
130 
131             if (modified) {
132                 mStore.writeIpConfigurations(filepath, mIpConfigurations);
133             }
134         }
135     }
136 
getIpConfigurations()137     public ArrayMap<String, IpConfiguration> getIpConfigurations() {
138         synchronized (mSync) {
139             return new ArrayMap<>(mIpConfigurations);
140         }
141     }
142 
143     @Nullable
getIpConfigurationForDefaultInterface()144     public IpConfiguration getIpConfigurationForDefaultInterface() {
145         return null;
146     }
147 }
148