• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.settings;
16 
17 import static android.content.pm.PackageManager.FEATURE_ETHERNET;
18 import static android.content.pm.PackageManager.FEATURE_WIFI;
19 
20 import android.app.Service;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.SharedPreferences;
24 import android.content.pm.PackageManager;
25 import android.content.pm.ResolveInfo;
26 import android.net.NetworkTemplate;
27 import android.net.Uri;
28 import android.os.IBinder;
29 import android.os.storage.StorageManager;
30 import android.os.storage.VolumeInfo;
31 import android.telephony.SubscriptionInfo;
32 import android.telephony.SubscriptionManager;
33 import android.telephony.TelephonyManager;
34 import android.util.IndentingPrintWriter;
35 import android.util.Log;
36 
37 import androidx.annotation.VisibleForTesting;
38 
39 import com.android.settings.applications.ProcStatsData;
40 import com.android.settings.datausage.lib.DataUsageLib;
41 import com.android.settings.fuelgauge.batterytip.AnomalyConfigJobService;
42 import com.android.settings.network.MobileNetworkRepository;
43 import com.android.settingslib.net.DataUsageController;
44 
45 import org.json.JSONArray;
46 import org.json.JSONException;
47 import org.json.JSONObject;
48 
49 import java.io.File;
50 import java.io.FileDescriptor;
51 import java.io.PrintWriter;
52 
53 public class SettingsDumpService extends Service {
54 
55     public static final String EXTRA_KEY_SHOW_NETWORK_DUMP = "show_network_dump";
56 
57     private static final String TAG = "SettingsDumpService";
58     @VisibleForTesting
59     static final String KEY_SERVICE = "service";
60     @VisibleForTesting
61     static final String KEY_STORAGE = "storage";
62     @VisibleForTesting
63     static final String KEY_DATAUSAGE = "datausage";
64     @VisibleForTesting
65     static final String KEY_MEMORY = "memory";
66     @VisibleForTesting
67     static final String KEY_DEFAULT_BROWSER_APP = "default_browser_app";
68     @VisibleForTesting
69     static final String KEY_ANOMALY_DETECTION = "anomaly_detection";
70     @VisibleForTesting
71     static final Intent BROWSER_INTENT =
72             new Intent("android.intent.action.VIEW", Uri.parse("http://"));
73 
74     private boolean mShouldShowNetworkDump = false;
75 
76     @Override
onStartCommand(Intent intent, int flags, int startId)77     public int onStartCommand(Intent intent, int flags, int startId) {
78         if (intent != null) {
79             mShouldShowNetworkDump = intent.getBooleanExtra(EXTRA_KEY_SHOW_NETWORK_DUMP, false);
80         }
81         return Service.START_REDELIVER_INTENT;
82     }
83 
84     @Override
onBind(Intent intent)85     public IBinder onBind(Intent intent) {
86         return null;
87     }
88 
89     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)90     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
91         IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
92         if (!mShouldShowNetworkDump) {
93             JSONObject dump = new JSONObject();
94             pw.println(TAG + ": ");
95             pw.increaseIndent();
96             try {
97                 dump.put(KEY_SERVICE, "Settings State");
98                 dump.put(KEY_STORAGE, dumpStorage());
99                 dump.put(KEY_DATAUSAGE, dumpDataUsage());
100                 dump.put(KEY_MEMORY, dumpMemory());
101                 dump.put(KEY_DEFAULT_BROWSER_APP, dumpDefaultBrowser());
102                 dump.put(KEY_ANOMALY_DETECTION, dumpAnomalyDetection());
103             } catch (Exception e) {
104                 Log.w(TAG, "exception in dump: ", e);
105             }
106             pw.println(dump);
107             pw.flush();
108             pw.decreaseIndent();
109         } else {
110             dumpMobileNetworkSettings(pw);
111         }
112     }
113 
dumpMemory()114     private JSONObject dumpMemory() throws JSONException {
115         JSONObject obj = new JSONObject();
116         ProcStatsData statsManager = new ProcStatsData(this, false);
117         statsManager.refreshStats(true);
118         ProcStatsData.MemInfo memInfo = statsManager.getMemInfo();
119 
120         obj.put("used", String.valueOf(memInfo.realUsedRam));
121         obj.put("free", String.valueOf(memInfo.realFreeRam));
122         obj.put("total", String.valueOf(memInfo.realTotalRam));
123         obj.put("state", statsManager.getMemState());
124 
125         return obj;
126     }
127 
dumpDataUsage()128     private JSONObject dumpDataUsage() throws JSONException {
129         JSONObject obj = new JSONObject();
130         DataUsageController controller = new DataUsageController(this);
131         SubscriptionManager manager = this.getSystemService(SubscriptionManager.class);
132         TelephonyManager telephonyManager = this.getSystemService(TelephonyManager.class);
133         final PackageManager packageManager = this.getPackageManager();
134         if (telephonyManager.isDataCapable()) {
135             JSONArray array = new JSONArray();
136             for (SubscriptionInfo info : manager.getAvailableSubscriptionInfoList()) {
137                 NetworkTemplate template = DataUsageLib.getMobileTemplateForSubId(
138                         telephonyManager, info.getSubscriptionId());
139                 final JSONObject usage = dumpDataUsage(template, controller);
140                 usage.put("subId", info.getSubscriptionId());
141                 array.put(usage);
142             }
143             obj.put("cell", array);
144         }
145         if (packageManager.hasSystemFeature(FEATURE_WIFI)) {
146             obj.put("wifi", dumpDataUsage(
147                     new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build(), controller));
148         }
149 
150         if (packageManager.hasSystemFeature(FEATURE_ETHERNET)) {
151             obj.put("ethernet", dumpDataUsage(new NetworkTemplate.Builder(
152                     NetworkTemplate.MATCH_ETHERNET).build(), controller));
153         }
154         return obj;
155     }
156 
dumpDataUsage(NetworkTemplate template, DataUsageController controller)157     private JSONObject dumpDataUsage(NetworkTemplate template, DataUsageController controller)
158             throws JSONException {
159         JSONObject obj = new JSONObject();
160         DataUsageController.DataUsageInfo usage = controller.getDataUsageInfo(template);
161         obj.put("carrier", usage.carrier);
162         obj.put("start", usage.startDate);
163         obj.put("usage", usage.usageLevel);
164         obj.put("warning", usage.warningLevel);
165         obj.put("limit", usage.limitLevel);
166         return obj;
167     }
168 
dumpStorage()169     private JSONObject dumpStorage() throws JSONException {
170         JSONObject obj = new JSONObject();
171         StorageManager manager = getSystemService(StorageManager.class);
172         for (VolumeInfo volume : manager.getVolumes()) {
173             JSONObject volObj = new JSONObject();
174             if (volume.isMountedReadable()) {
175                 File path = volume.getPath();
176                 volObj.put("used", String.valueOf(path.getTotalSpace() - path.getFreeSpace()));
177                 volObj.put("total", String.valueOf(path.getTotalSpace()));
178             }
179             volObj.put("path", volume.getInternalPath());
180             volObj.put("state", volume.getState());
181             volObj.put("stateDesc", volume.getStateDescription());
182             volObj.put("description", volume.getDescription());
183             obj.put(volume.getId(), volObj);
184         }
185         return obj;
186     }
187 
188     @VisibleForTesting
dumpDefaultBrowser()189     String dumpDefaultBrowser() {
190         final ResolveInfo resolveInfo = getPackageManager().resolveActivity(
191                 BROWSER_INTENT, PackageManager.MATCH_DEFAULT_ONLY);
192 
193         if (resolveInfo == null || resolveInfo.activityInfo.packageName.equals("android")) {
194             return null;
195         } else {
196             return resolveInfo.activityInfo.packageName;
197         }
198     }
199 
200     @VisibleForTesting
dumpAnomalyDetection()201     JSONObject dumpAnomalyDetection() throws JSONException {
202         final JSONObject obj = new JSONObject();
203         final SharedPreferences sharedPreferences = getSharedPreferences(
204                 AnomalyConfigJobService.PREF_DB,
205                 Context.MODE_PRIVATE);
206         final int currentVersion = sharedPreferences.getInt(
207                 AnomalyConfigJobService.KEY_ANOMALY_CONFIG_VERSION,
208                 0 /* defValue */);
209         obj.put("anomaly_config_version", String.valueOf(currentVersion));
210 
211         return obj;
212     }
213 
dumpMobileNetworkSettings(IndentingPrintWriter writer)214     private void dumpMobileNetworkSettings(IndentingPrintWriter writer) {
215         MobileNetworkRepository.getInstance(this).dump(writer);
216     }
217 }
218