how to check if a function exist in bash script

how to check if a function exist in bash script

#!/bin/bash

aaa() {
    echo "in a function"
}

if [ "$(type -t $1)" = "function" ]; then
  echo "$1 is a function"
else
  echo "$1 is not a function"
fi
$ ./test.sh aaa
function
aaa is not a function
$ ./test.sh aab
aab is not a function

Permission to install an application like Google Play did

your app must be put in /vendor/priv-app/ or /system/priv-app/ to get PRIVATE_FLAG_PRIVILEGED

https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/pm/Settings.java;drc=d31ee388115d17c2fd337f2806b37390c7d29834;l=3596

and also add the permission.xml and Android.mk as below:

<?xml version="1.0" encoding="utf-8"?>

<permissions>
    <privapp-permissions package="com.idtech.appmanager">
        <permission name="android.permission.DELETE_PACKAGES"/>
        <permission name="android.permission.INSTALL_PACKAGES"/>
    </privapp-permissions>
    <privapp-permissions package="com.example.android.apis">
        <permission name="android.permission.INSTALL_PACKAGES"/>
    </privapp-permissions>
</permissions>                                                                                                                                                                                              
include $(CLEAR_VARS)
LOCAL_MODULE := permissions.xml                                                                                                                                               
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC 
LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT_ETC)/permissions
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_PRODUCT_MODULE := true
include $(BUILD_PREBUILT)

then your app can get permission to trigger installation without set “install from unknown source"

https://cs.android.com/android/platform/superproject/+/master:frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java;drc=0461f6fd4d7bab47da1f6567ccd8c84ca548ab89;l=84

AOSP also has a demo app for package installation

https://cs.android.com/android/platform/superproject/+/master:development/samples/ApiDemos/src/com/example/android/apis/content/InstallApkSessionApi.java

below changes are needed for the ApiDemos to get permission of installation

+++ b/samples/ApiDemos/Android.mk
@@ -23,6 +23,8 @@ LOCAL_DEX_PREOPT := false
 
 LOCAL_COMPATIBILITY_SUITE := device-tests
 
+LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT_APPS_PRIVILEGED)
+
 include $(BUILD_PACKAGE)
 
 # Use the folloing include to make our test apk.
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index 2d2d785dda..811c3204f4 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -41,6 +41,7 @@
     <uses-permission android:name="android.permission.WAKE_LOCK"/>
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
+    <uses-permission android:name="android.permission.INSTALL_PACKAGES"/>

then you can install an app just like google play does

I also create a tiny example of silent install

https://github.com/wenchiching/silentinstall

you can clone and build app from above git, then follow above description install the app to /system/priv-app/ or /vendor/priv-app

Fastboot HAL module implemetation

I was trying to have “fastboot format userdata" work in user space fastboot

but some how I “adb reboot fastboot" and device go to user space fastboot but always fail to perform “fastboot format userdata"

looking into the source, there are 2 things need to be done

  1. Fastboot HAL add to PRODUCT_PACKAGES
  2. implement the Fastboot HAL module

https://android-review.googlesource.com/c/device/google/muskie/+/1473229 add android.hardware.fastboot@1.0-impl-mock

https://android-review.googlesource.com/c/platform/hardware/libhardware/+/1473557 Add fastboot.h for Fastboot OEM HAL

https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1473621 implement Fastboot OEM HAL of getPartitionType

https://android-review.googlesource.com/c/platform/build/+/1473622 add owenwen to vendor module list

and I create vendor/owenwen/fastboot for my fastboot module

Android.bp

cc_library_shared {

    name: "fastboot.default",

    //recovery_available: true, // not work, this setting won't install the module into recovery image
    recovery: true,

    relative_install_path: "hw",

    include_dirs: [
        "hardware/libhardware/include",
    ],

    srcs: ["Fastboot.cpp"],

    owner: "owenwen",
}

Fastboot.cpp

#include <hardware/hardware.h>
#include <hardware/fastboot.h>
#include <cstring>

#define USERDATA "userdata"

static struct hw_module_methods_t fastboot_module_methods = {
        .open = NULL,
};

/* refer hardware/interfaces/fastboot/1.0/types.hal for the return value of this function
 * 0: EXT4
 * 1: F2FS
 * 2: RAW
 */
static int module_getPartitionType(fastboot_module_t* /*module*/, const char* partitionName) {
        if (std::strncmp(partitionName, USERDATA, std::strlen(USERDATA)) == 0) {
                return 0;
        } else {
                return 2;
        }
}

fastboot_module_t HAL_MODULE_INFO_SYM = {
        .common = {
                .tag = HARDWARE_MODULE_TAG,
                .version_major = 1,
                .version_minor = 0,
                .id = FASTBOOT_MODULE_ID,
                .name = "Fastboot HAL Module",
                .author = "Owen Wen",
                .methods = &fastboot_module_methods,
        },
        .getPartitionType = module_getPartitionType,
};

How to remove notify in Android O, customize AOSP

https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java;drc=b61408add5839a01f40809fc05608af244c0e47d;l=5296

There is no config to turn on/off the notification, so can only customize the AOSP source code

    private boolean isBlocked(NotificationRecord r) {
        final String pkg = r.sbn.getPackageName();
        final int callingUid = r.sbn.getUid();
        return mPreferencesHelper.isGroupBlocked(pkg, callingUid, r.getChannel().getGroup())
                || mPreferencesHelper.getImportance(pkg, callingUid)
                == NotificationManager.IMPORTANCE_NONE
                || r.getImportance() == NotificationManager.IMPORTANCE_NONE;
    }

How to change Android PiP default location programmatically

refer to below commit, this setting help to change the default location of PIP window

please refer to  https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/Gravity.java;l=45 to find out the value you need

e.g. Gravity.TOP | Gravity.RIGHT is 0x35

commit 06868c37df46c0c973a96a0a25b1f301384db4be
Author: Winson <winsonc@google.com>
Date:   Wed Oct 12 21:08:18 2016 -0700

    Changing initial PIP bounds specifications.
    
    - Change from a absolute bounds to a size, gravity and inset to
      allow easier tweaking of initial pinned stack bounds.
    
    Test: android.server.cts.ActivityManagerPinnedStackTests
    Test: #testPinnedStackDefaultBounds
    Test: #testPinnedStackMovementBounds
    
    Change-Id: I82a102bbd2d83259c6c84915071d1a16728e3aa7

diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index c40436a5bda..30dcfb081d8 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2482,8 +2482,17 @@
          -->
     <integer name="config_navBarOpacityMode">0</integer>
 
-    <!-- Default bounds [left top right bottom] on screen for picture-in-picture windows. -->
-    <string translatable="false" name="config_defaultPictureInPictureBounds">"0 0 100 100"</string>
+    <!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
+         These values are in DPs and will be converted to pixel sizes internally. -->
+    <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">10x10</string>
+
+    <!-- Max default size [WIDTHxHEIGHT] on screen for picture-in-picture windows to fit inside.
+         These values are in DPs and will be converted to pixel sizes internally. -->
+    <string translatable="false" name="config_defaultPictureInPictureSize">216x135</string>
+
+    <!-- The default gravity for the picture-in-picture window.
+         Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT -->
+    <integer name="config_defaultPictureInPictureGravity">0x55</integer>