1 /* 2 * Copyright (C) 2021 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 package com.android.car.bugreport; 17 18 import android.app.ActivityThread; 19 import android.os.Build; 20 import android.os.SystemProperties; 21 import android.provider.DeviceConfig; 22 import android.util.Log; 23 24 import com.android.internal.annotations.GuardedBy; 25 26 import com.google.common.collect.ImmutableSet; 27 28 import java.io.PrintWriter; 29 30 /** 31 * Contains config for BugReport App. 32 * 33 * <p>The config is kept synchronized with {@code car} namespace. It's not defined in 34 * {@link DeviceConfig}. 35 * 36 * <ul>To get/set the flags via adb: 37 * <li>{@code adb shell device_config get car bugreport_upload_destination} 38 * <li>{@code adb shell device_config put car bugreport_upload_destination gcs} 39 * <li>{@code adb shell device_config delete car bugreport_upload_destination} 40 * </ul> 41 */ 42 final class Config { 43 private static final String TAG = Config.class.getSimpleName(); 44 45 /** 46 * Namespace for all Android Automotive related features. 47 * 48 * <p>In the future it will move to {@code DeviceConfig#NAMESPACE_CAR}. 49 */ 50 private static final String NAMESPACE_CAR = "car"; 51 52 /** 53 * A string flag, can be one of {@code null} or {@link #UPLOAD_DESTINATION_GCS}. 54 */ 55 private static final String KEY_BUGREPORT_UPLOAD_DESTINATION = "bugreport_upload_destination"; 56 57 /** 58 * A value for {@link #KEY_BUGREPORT_UPLOAD_DESTINATION}. 59 * 60 * Upload bugreports to GCS. Only works in {@code userdebug} or {@code eng} builds. 61 */ 62 private static final String UPLOAD_DESTINATION_GCS = "gcs"; 63 64 /** 65 * A system property to force enable the app bypassing the {@code userdebug/eng} build check. 66 */ 67 private static final String PROP_FORCE_ENABLE = "android.car.bugreport.force_enable"; 68 69 /* 70 * Enable uploading new bugreports to GCS for these devices. If the device is not in this list, 71 * {@link #KEY_UPLOAD_DESTINATION} flag will be used instead. 72 */ 73 private static final ImmutableSet<String> ENABLE_FORCE_UPLOAD_TO_GCS_FOR_DEVICES = 74 ImmutableSet.of("hawk", "seahawk"); 75 76 private final Object mLock = new Object(); 77 78 @GuardedBy("mLock") 79 private String mUploadDestination = null; 80 create()81 static Config create() { 82 Config config = new Config(); 83 config.start(); 84 return config; 85 } 86 Config()87 private Config() {} 88 start()89 private void start() { 90 DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_CAR, 91 ActivityThread.currentApplication().getMainExecutor(), this::onPropertiesChanged); 92 updateConstants(); 93 } 94 onPropertiesChanged(DeviceConfig.Properties properties)95 private void onPropertiesChanged(DeviceConfig.Properties properties) { 96 if (properties.getKeyset().contains(KEY_BUGREPORT_UPLOAD_DESTINATION)) { 97 updateConstants(); 98 } 99 } 100 101 /** Returns true if bugreport app is enabled for this device. */ isBugReportEnabled()102 static boolean isBugReportEnabled() { 103 return Build.IS_DEBUGGABLE || SystemProperties.getBoolean(PROP_FORCE_ENABLE, false); 104 } 105 106 /** If new bugreports should be scheduled for uploading. */ getAutoUpload()107 boolean getAutoUpload() { 108 // TODO(b/144851443): Enable auto-upload only if upload destination is Gcs until 109 // we create a way to allow implementing OEMs custom upload logic. 110 return isUploadDestinationGcs(); 111 } 112 113 /** 114 * Returns {@link true} if bugreport upload destination is GCS. 115 */ isUploadDestinationGcs()116 private boolean isUploadDestinationGcs() { 117 if (isTempForceAutoUploadGcsEnabled()) { 118 Log.d(TAG, "Setting upload dest to GCS ENABLE_AUTO_UPLOAD is true"); 119 return true; 120 } 121 // NOTE: enable it only for userdebug/eng builds. 122 return UPLOAD_DESTINATION_GCS.equals(getUploadDestination()) && Build.IS_DEBUGGABLE; 123 } 124 isTempForceAutoUploadGcsEnabled()125 private static boolean isTempForceAutoUploadGcsEnabled() { 126 return ENABLE_FORCE_UPLOAD_TO_GCS_FOR_DEVICES.contains(Build.DEVICE); 127 } 128 129 /** 130 * Returns value of a flag {@link #KEY_BUGREPORT_UPLOAD_DESTINATION}. 131 */ getUploadDestination()132 private String getUploadDestination() { 133 synchronized (mLock) { 134 return mUploadDestination; 135 } 136 } 137 updateConstants()138 private void updateConstants() { 139 synchronized (mLock) { 140 mUploadDestination = DeviceConfig.getString(NAMESPACE_CAR, 141 KEY_BUGREPORT_UPLOAD_DESTINATION, /* defaultValue= */ null); 142 } 143 } 144 dump(String prefix, PrintWriter pw)145 void dump(String prefix, PrintWriter pw) { 146 pw.println(prefix + "car.bugreport.Config:"); 147 148 pw.print(prefix + " "); 149 pw.print("getAutoUpload"); 150 pw.print("="); 151 pw.println(getAutoUpload() ? "true" : "false"); 152 153 pw.print(prefix + " "); 154 pw.print("getUploadDestination"); 155 pw.print("="); 156 pw.println(getUploadDestination()); 157 158 pw.print(prefix + " "); 159 pw.print("isUploadDestinationGcs"); 160 pw.print("="); 161 pw.println(isUploadDestinationGcs()); 162 } 163 } 164