Merge "Add debugfs support for cuttlefish." into rvc-dev
diff --git a/guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.cpp b/guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.cpp
index b67544c..16185b5 100644
--- a/guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.cpp
+++ b/guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.cpp
@@ -106,6 +106,10 @@
     auto buff = static_cast<char*>(GetBuffer(current_offset));
     while (size > 0) {
       auto written = screen_server_->Write(buff, size);
+      if (written == -1) {
+        ALOGE("Broadcaster thread failed to write frame: %s", strerror(errno));
+        break;
+      }
       size -= written;
       buff += written;
     }
diff --git a/guest/monitoring/cuttlefish_service/Android.mk b/guest/monitoring/cuttlefish_service/Android.mk
index 2540ef5..b08adaf 100644
--- a/guest/monitoring/cuttlefish_service/Android.mk
+++ b/guest/monitoring/cuttlefish_service/Android.mk
@@ -15,12 +15,12 @@
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_CERTIFICATE := platform
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := $(call all-java-files-under, java)
 LOCAL_STATIC_JAVA_LIBRARIES := guava
 LOCAL_PACKAGE_NAME := CuttlefishService
 LOCAL_SDK_VERSION := 28
+LOCAL_PRIVILEGED_MODULE := true
 LOCAL_PROGUARD_FLAGS := -include build/core/proguard.flags
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 LOCAL_PROGUARD_ENABLED := obfuscation
diff --git a/guest/monitoring/cuttlefish_service/AndroidManifest.xml b/guest/monitoring/cuttlefish_service/AndroidManifest.xml
index 85abd09..428445a 100644
--- a/guest/monitoring/cuttlefish_service/AndroidManifest.xml
+++ b/guest/monitoring/cuttlefish_service/AndroidManifest.xml
@@ -1,21 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.google.gce.gceservice"
-    android:sharedUserId="android.uid.system">
+    package="com.android.google.gce.gceservice">
 
     <uses-sdk android:minSdkVersion="5" />
 
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
-    <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
-    <uses-permission android:name="android.permission.DUMP" />
 
     <application
         android:label="GceService"
diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java
index 754eb8f..7b8d864 100644
--- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java
+++ b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java
@@ -20,10 +20,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
 import android.util.Log;
 
-import com.android.google.gce.gceservice.GceService;
 
 public class GceBroadcastReceiver extends BroadcastReceiver {
     private static final String LOG_TAG = "GceBroadcastReceiver";
@@ -32,7 +30,7 @@
     private void reportIntent(Context context, String intentType) {
         Intent intent = new Intent(context, GceService.class);
         intent.setAction(intentType);
-        context.startService(intent);
+        context.startForegroundService(intent);
     }
 
 
diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceService.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceService.java
index b070377..34f3b1a 100644
--- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceService.java
+++ b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceService.java
@@ -15,13 +15,16 @@
  */
 package com.android.google.gce.gceservice;
 
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
 import android.app.Service;
 import android.bluetooth.BluetoothAdapter;
+import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
 import android.util.Log;
-import android.os.Binder;
 import android.os.IBinder;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -37,11 +40,12 @@
     public static final String INTENT_ACTION_CONFIGURE = "com.android.google.gce.gceservice.CONFIGURE";
     public static final String INTENT_ACTION_NETWORK_CHANGED = "com.android.google.gce.gceservice.NETWORK_CHANGED";
     public static final String INTENT_ACTION_BLUETOOTH_CHANGED = "com.android.google.gce.gceservice.BLUETOOTH_CHANGED";
-    private static final int NETWORK_OR_BOOT_TIMEOUT = 30;
+    private static final String NOTIFICATION_CHANNEL_ID = "cuttlefish-service";
+    private static final String NOTIFICATION_CHANNEL_NAME = "Cuttlefish Service";
+    private static final int NOTIFICATION_ID = 1;
 
     private final JobExecutor mExecutor = new JobExecutor();
     private final LocationServicesManager mLocationServices = new LocationServicesManager(this);
-    private final PackageVerifierManager mPackageVerifier = new PackageVerifierManager(this);
     private final PackageVerificationConsentEnforcer mConsentEnforcer = new PackageVerificationConsentEnforcer(this);
     private final BootReporter mBootReporter = new BootReporter();
     private final GceBroadcastReceiver mBroadcastReceiver = new GceBroadcastReceiver();
@@ -66,7 +70,6 @@
             mWifiManager = new GceWifiManager(this, mBootReporter, mExecutor);
 
             mExecutor.schedule(mLocationServices);
-            mExecutor.schedule(mPackageVerifier);
             mExecutor.schedule(mConsentEnforcer);
             mExecutor.schedule(mWifiManager);
             mExecutor.schedule(mBluetoothChecker);
@@ -77,10 +80,19 @@
 
             mExecutor.schedule(mBootReporter,
                     mLocationServices.getLocationServicesReady(),
-                    mPackageVerifier.getPackageVerifierReady(),
                     mBluetoothChecker.getEnabled()
                     // mTombstoneChecker.getTombstoneResult()
                     );
+
+            NotificationManager notificationManager =
+                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+            NotificationChannel channel =
+                    new NotificationChannel(
+                            NOTIFICATION_CHANNEL_ID,
+                            NOTIFICATION_CHANNEL_NAME,
+                            NotificationManager.IMPORTANCE_LOW);
+            notificationManager.createNotificationChannel(channel);
+
         } catch (Exception e) {
             Log.e(LOG_TAG, "Exception caught", e);
         }
@@ -120,6 +132,15 @@
             Log.e(LOG_TAG, "Missing intent action.");
         }
 
+        Notification notification =
+                new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
+                        .setAutoCancel(true)
+                        .setContentTitle("Cuttlefish service is running.")
+                        .setSmallIcon(android.R.drawable.ic_dialog_info)
+                        .setTimeoutAfter(10000)
+                        .build();
+        startForeground(NOTIFICATION_ID, notification);
+
         if (INTENT_ACTION_CONFIGURE.equals(mMostRecentAction)) {
             mExecutor.schedule(mConnChecker);
         } else if (INTENT_ACTION_NETWORK_CHANGED.equals(mMostRecentAction)) {
@@ -128,10 +149,17 @@
             mExecutor.schedule(mBluetoothChecker);
         }
 
+        stopForeground(Service.STOP_FOREGROUND_DETACH);
+
         /* If anything goes wrong, make sure we receive intent again. */
         return Service.START_STICKY;
     }
 
+    @Override
+    public void onDestroy() {
+        unregisterReceiver(mBroadcastReceiver);
+    }
+
     /** Dump the virtual device state
      */
     @Override
@@ -145,8 +173,6 @@
         pw.println("Current system service state:");
         pw.println("  Location service ready: "
             + mLocationServices.getLocationServicesReady().isDone());
-        pw.println("  Package verifier ready: "
-            + mPackageVerifier.getPackageVerifierReady().isDone());
         pw.println("  Network connected: " + mConnChecker.getConnected().isDone());
         pw.println("  WiFi configured: " + mWifiManager.getWifiReady().isDone());
         pw.println("  Bluetooth enabled: " + mBluetoothChecker.getEnabled().isDone());
diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java
deleted file mode 100644
index e10845a..0000000
--- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.google.gce.gceservice;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.util.Log;
-
-/**
- * Disable package verifier.
- */
-public class PackageVerifierManager extends JobBase {
-    private static final String LOG_TAG = "GcePackageVerifierManager";
-    private static final String SETTING_PACKAGE_VERIFIER_ENABLE = "verifier_verify_adb_installs";
-    private final Context mContext;
-    private final GceFuture<Boolean> mResult =
-            new GceFuture<Boolean>("Package Verifier");
-
-
-    PackageVerifierManager(Context context) {
-        super(LOG_TAG);
-        mContext = context;
-    }
-
-
-    private boolean getAndLogPackageVerifierState() {
-        int package_verifier_state = 1;
-        try {
-            ContentResolver contentResolver = mContext.getContentResolver();
-            package_verifier_state = Settings.Secure.getInt(contentResolver, SETTING_PACKAGE_VERIFIER_ENABLE);
-        } catch (SettingNotFoundException e) {
-            Log.w(LOG_TAG, "Could not read package verifier state. Assuming it's enabled.");
-        }
-
-        return package_verifier_state != 0;
-    }
-
-
-    public int execute() {
-        if (getAndLogPackageVerifierState()) {
-            Settings.Secure.putInt(mContext.getContentResolver(), SETTING_PACKAGE_VERIFIER_ENABLE, 0);
-            // One more call, just to log the state.
-            getAndLogPackageVerifierState();
-        }
-
-        mResult.set(true);
-        return 0;
-    }
-
-
-    public void onDependencyFailed(Exception e) {
-        Log.e(LOG_TAG, "Could not disable Package Verifier.", e);
-        mResult.set(e);
-    }
-
-
-    public GceFuture<Boolean> getPackageVerifierReady() {
-        return mResult;
-    }
-}
diff --git a/shared/auto/manifest.xml b/shared/auto/manifest.xml
index 0435a55..2c1361e 100644
--- a/shared/auto/manifest.xml
+++ b/shared/auto/manifest.xml
@@ -31,15 +31,6 @@
     </hal>
     -->
     <hal format="hidl">
-        <name>android.hardware.automotive.vehicle</name>
-        <transport>hwbinder</transport>
-        <version>2.0</version>
-        <interface>
-            <name>IVehicle</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
         <name>android.hardware.automotive.can</name>
         <transport>hwbinder</transport>
         <version>1.0</version>
diff --git a/shared/config/fstab.ext4 b/shared/config/fstab.ext4
new file mode 100644
index 0000000..3e3672f
--- /dev/null
+++ b/shared/config/fstab.ext4
@@ -0,0 +1,14 @@
+boot /boot emmc defaults recoveryonly
+system /system ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect
+# Add all non-dynamic partitions except system, after this comment
+/dev/block/by-name/userdata /data ext4 nodev,noatime,nosuid,errors=panic wait,fileencryption=aes-256-xts:aes-256-cts,fsverity
+/dev/block/by-name/cache /cache ext4 nodev,noatime,nosuid,errors=panic wait
+/dev/block/by-name/metadata /metadata ext4 nodev,noatime,nosuid,errors=panic wait,formattable,first_stage_mount
+/dev/block/by-name/misc /misc emmc defaults defaults
+# Add all dynamic partitions except system, after this comment
+odm /odm ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect
+product /product ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect
+system_ext /system_ext ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect
+vendor /vendor ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect
+/dev/block/zram0 none swap defaults zramsize=75%
+/tmp /sdcard none defaults,bind recoveryonly
diff --git a/shared/device.mk b/shared/device.mk
index cced06d..d1de19a 100644
--- a/shared/device.mk
+++ b/shared/device.mk
@@ -77,6 +77,9 @@
 PRODUCT_PROPERTY_OVERRIDES += \
     wlan.driver.status=ok
 
+# Enforce privapp-permissions whitelist.
+PRODUCT_PROPERTY_OVERRIDES += ro.control_privapp_permissions=enforce
+
 # aes-256-heh default is not supported in standard kernels.
 PRODUCT_PROPERTY_OVERRIDES += ro.crypto.volume.filenames_mode=aes-256-cts
 
@@ -152,7 +155,8 @@
 # Packages for testing
 #
 PRODUCT_PACKAGES += \
-    aidl_lazy_test_server
+    aidl_lazy_test_server \
+    hidl_lazy_test_server
 
 DEVICE_PACKAGE_OVERLAYS := device/google/cuttlefish/shared/overlay
 # PRODUCT_AAPT_CONFIG and PRODUCT_AAPT_PREF_CONFIG are intentionally not set to
@@ -173,6 +177,7 @@
     device/google/cuttlefish/shared/config/media_codecs_google_video.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_video.xml \
     device/google/cuttlefish/shared/config/media_codecs_performance.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_performance.xml \
     device/google/cuttlefish/shared/config/media_profiles.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_profiles_V1_0.xml \
+    device/google/cuttlefish/shared/permissions/privapp-permissions-cuttlefish.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/privapp-permissions-cuttlefish.xml \
     frameworks/av/media/libeffects/data/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
     frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_audio.xml \
     frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_telephony.xml \
@@ -204,9 +209,20 @@
     frameworks/native/data/etc/android.software.app_widgets.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.app_widgets.xml \
     system/bt/vendor_libs/test_vendor_lib/data/controller_properties.json:vendor/etc/bluetooth/controller_properties.json \
     device/google/cuttlefish/shared/config/task_profiles.json:$(TARGET_COPY_OUT_VENDOR)/etc/task_profiles.json \
+
+ifeq ($(TARGET_USERDATAIMAGE_FILE_SYSTEM_TYPE),f2fs)
+PRODUCT_COPY_FILES += \
     device/google/cuttlefish/shared/config/fstab:$(TARGET_COPY_OUT_RAMDISK)/fstab.cutf_cvm \
     device/google/cuttlefish/shared/config/fstab:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.cutf_cvm \
-    device/google/cuttlefish/shared/config/fstab:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.cutf_cvm \
+    device/google/cuttlefish/shared/config/fstab:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.cutf_cvm
+endif
+
+ifeq ($(TARGET_USERDATAIMAGE_FILE_SYSTEM_TYPE),ext4)
+PRODUCT_COPY_FILES += \
+    device/google/cuttlefish/shared/config/fstab.ext4:$(TARGET_COPY_OUT_RAMDISK)/fstab.cutf_cvm \
+    device/google/cuttlefish/shared/config/fstab.ext4:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.cutf_cvm \
+    device/google/cuttlefish/shared/config/fstab.ext4:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.cutf_cvm
+endif
 
 ifeq ($(TARGET_VULKAN_SUPPORT),true)
 PRODUCT_COPY_FILES += \
diff --git a/shared/permissions/privapp-permissions-cuttlefish.xml b/shared/permissions/privapp-permissions-cuttlefish.xml
new file mode 100644
index 0000000..7c3dcaa
--- /dev/null
+++ b/shared/permissions/privapp-permissions-cuttlefish.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<permissions>
+    <privapp-permissions package="com.android.google.gce.gceservice">
+        <permission name="android.permission.ACCESS_NETWORK_STATE" />
+        <permission name="android.permission.ACCESS_WIFI_STATE" />
+        <permission name="android.permission.CHANGE_WIFI_STATE" />
+        <permission name="android.permission.FOREGROUND_SERVICE" />
+        <permission name="android.permission.INTERNET" />
+        <permission name="android.permission.RECEIVE_BOOT_COMPLETED" />
+        <permission name="android.permission.WRITE_EXTERNAL_STORAGE" />
+        <permission name="android.permission.WRITE_SETTINGS" />
+        <permission name="android.permission.BLUETOOTH" />
+    </privapp-permissions>
+</permissions>
diff --git a/shared/sepolicy/vendor/seapp_contexts b/shared/sepolicy/vendor/seapp_contexts
index e325c99..820c416 100644
--- a/shared/sepolicy/vendor/seapp_contexts
+++ b/shared/sepolicy/vendor/seapp_contexts
@@ -1,2 +1,2 @@
 # GceService app
-user=system seinfo=platform name=com.android.google.gce.gceservice domain=gceservice type=app_data_file
+user=_app isPrivApp=true seinfo=default name=com.android.google.gce.gceservice domain=gceservice type=app_data_file
diff --git a/tests/hal/hal_implementation_test.cpp b/tests/hal/hal_implementation_test.cpp
index baf3afe..2c33483 100644
--- a/tests/hal/hal_implementation_test.cpp
+++ b/tests/hal/hal_implementation_test.cpp
@@ -133,7 +133,7 @@
         "android.system",
     };
     for (const std::string& package : kAospPackages) {
-        if (name.inPackage(package) && !isHidlPackageWhitelist(name)) {
+        if (name.inPackage(package)) {
             return true;
         }
     }
@@ -197,6 +197,7 @@
 
     for (const FQName& f : allTreeHidlInterfaces()) {
         if (!isAospHidlInterface(f)) continue;
+        if (isHidlPackageWhitelist(f)) continue;
 
         unimplemented[f.package()][f.getPackageMajorVersion()].insert(f.getPackageMinorVersion());
     }