1 /* 2 * Copyright (C) 2019 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.google.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"); 75 76 private final Object mLock = new Object(); 77 78 @GuardedBy("mLock") 79 private String mUploadDestination = null; 80 start()81 void start() { 82 DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_CAR, 83 ActivityThread.currentApplication().getMainExecutor(), this::onPropertiesChanged); 84 updateConstants(); 85 } 86 onPropertiesChanged(DeviceConfig.Properties properties)87 private void onPropertiesChanged(DeviceConfig.Properties properties) { 88 if (properties.getKeyset().contains(KEY_BUGREPORT_UPLOAD_DESTINATION)) { 89 updateConstants(); 90 } 91 } 92 93 /** Returns true if bugreport app is enabled for this device. */ isBugReportEnabled()94 static boolean isBugReportEnabled() { 95 return Build.IS_DEBUGGABLE || SystemProperties.getBoolean(PROP_FORCE_ENABLE, false); 96 } 97 98 /** If new bugreports should be scheduled for uploading. */ getAutoUpload()99 boolean getAutoUpload() { 100 // TODO(b/144851443): Enable auto-upload only if upload destination is Gcs until 101 // we create a way to allow implementing OEMs custom upload logic. 102 return isUploadDestinationGcs(); 103 } 104 105 /** 106 * Returns {@link true} if bugreport upload destination is GCS. 107 */ isUploadDestinationGcs()108 private boolean isUploadDestinationGcs() { 109 if (isTempForceAutoUploadGcsEnabled()) { 110 Log.d(TAG, "Setting upload dest to GCS ENABLE_AUTO_UPLOAD is true"); 111 return true; 112 } 113 // NOTE: enable it only for userdebug/eng builds. 114 return UPLOAD_DESTINATION_GCS.equals(getUploadDestination()) && Build.IS_DEBUGGABLE; 115 } 116 isTempForceAutoUploadGcsEnabled()117 private static boolean isTempForceAutoUploadGcsEnabled() { 118 return ENABLE_FORCE_UPLOAD_TO_GCS_FOR_DEVICES.contains(Build.DEVICE); 119 } 120 121 /** 122 * Returns value of a flag {@link #KEY_BUGREPORT_UPLOAD_DESTINATION}. 123 */ getUploadDestination()124 private String getUploadDestination() { 125 synchronized (mLock) { 126 return mUploadDestination; 127 } 128 } 129 updateConstants()130 private void updateConstants() { 131 synchronized (mLock) { 132 mUploadDestination = DeviceConfig.getString(NAMESPACE_CAR, 133 KEY_BUGREPORT_UPLOAD_DESTINATION, /* defaultValue= */ null); 134 } 135 } 136 dump(String prefix, PrintWriter pw)137 void dump(String prefix, PrintWriter pw) { 138 pw.println(prefix + "car.bugreport.Config:"); 139 140 pw.print(prefix + " "); 141 pw.print("getAutoUpload"); 142 pw.print("="); 143 pw.println(getAutoUpload() ? "true" : "false"); 144 145 pw.print(prefix + " "); 146 pw.print("getUploadDestination"); 147 pw.print("="); 148 pw.println(getUploadDestination()); 149 150 pw.print(prefix + " "); 151 pw.print("isUploadDestinationGcs"); 152 pw.print("="); 153 pw.println(isUploadDestinationGcs()); 154 } 155 } 156