xref: /aosp_15_r20/prebuilts/sdk/create-android-plus-updatable-jar.sh (revision 344a7f5ef16c479e7a7f54ee6567a9d112f9e72b)
1#!/usr/bin/env bash
2#
3# Copyright 2024 - The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18set -e
19
20# This script was created to fix up some issues with the android.jar
21# files for `module-lib` and `system-server` in historical releases
22# 30 to 34. Modifying binary files is potentially dangerous so this was
23# created and put under version control to make it easy for someone to
24# verify the results if needed.
25
26# The basic function is:
27# * Save away a copy of the original android.jar, if not already
28#   present.
29# * Create a new android.jar that combines the original android.jar
30#   with the jars from the missing mainline modules.
31# * Add a README.md to explain what happened.
32
33SOURCE=${BASH_SOURCE[0]}
34SOURCE_DIR=$(dirname $SOURCE)
35
36# Change directory to top.
37cd $SOURCE_DIR/../..
38TOP=$PWD
39echo "Changed directory to $TOP; all paths are relative to that."
40SOURCE_DIR="prebuilts/sdk"
41
42if [[ $# == 0 ]]; then
43  echo "$SOURCE <version>+" >&2
44  exit 1
45fi
46
47VERSIONS=$@
48SURFACES=(
49  module-lib
50  system-server
51)
52
53function find_updatable_modules() {
54  typeset SURFACE=$1
55
56  # Scan the prebuilts/sdk numbered directories in the specified surface for
57  # jars. Exclude the following jars:
58  # 1. Any jar starting with android. That will exclude android.net.ipsec.ike
59  #    as well but that will be added explicitly below.
60  # 2. core-for-system-modules.jar as that is not an updatable module.
61  # 3. art as while that is an updatable module it must already be included in
62  #    the android.jar otherwise it would be unusable.
63  # 4. runtime-i18n as that is not updatable and must be included as it is
64  #    needed by art.
65  find $SOURCE_DIR -maxdepth 3 -type f -name \*.jar | \
66    grep -vE "/(android.*|core-for-system-modules|art|runtime-i18n)\.jar$" | \
67    grep -E "/[1-9][0-9]*/$SURFACE" | \
68    xargs -n1 basename | \
69    sort -u
70}
71
72# Add module-lib modules that do not fit into the standard naming pattern.
73MODULE_LIB_MODULES=(
74  android.net.ipsec.ike
75)
76
77# Add additional module-lib updatable modules.
78mapfile -O 1 -t MODULE_LIB_MODULES < <(find_updatable_modules module-lib)
79
80# Find all the system-server updatable modules.
81mapfile -t SYSTEM_SERVER_MODULES < <(find_updatable_modules system-server)
82
83for VERSION in $VERSIONS
84do
85  if ((VERSION < 30)); then
86    echo "$SOURCE: invalid version: $VERSION must be >= 30" >&2
87    exit 1
88  fi
89
90  VERSION_DIR=$SOURCE_DIR/$VERSION
91  if [ ! -d $VERSION_DIR ]; then
92    echo "$SOURCE: invalid version: $VERSION" >&2
93    exit 1
94  fi
95
96  for SURFACE in ${SURFACES[@]}
97  do
98    SURFACE_DIR=$VERSION_DIR/$SURFACE
99    if [ ! -d $SURFACE_DIR ]; then
100      echo "$SOURCE: $SURFACE_DIR does not exist" >&2
101      exit 1
102    fi
103
104    MODULE_LIB_DIR=$VERSION_DIR/module-lib
105
106
107    ANDROID_JAR=$SURFACE_DIR/android.jar
108
109    NEW_JAR=$SURFACE_DIR/android-plus-updatable.jar
110    rm -f $NEW_JAR
111
112    echo
113    echo "Merging the following jars into $NEW_JAR:"
114    echo "  $ANDROID_JAR"
115    JARS=$ANDROID_JAR
116
117    # Add all the module-lib jars to the list of jars to merge.
118    # These are always added, even for the system-server as the
119    # system-server directory only includes service-* modules but the
120    # system-server API surface is a super set of module-lib so should
121    # include everything that is in the module-lib updatable modules
122    # too.
123    for MODULE in ${MODULE_LIB_MODULES[@]}
124    do
125      MODULE_JAR=$MODULE_LIB_DIR/$MODULE
126      if [ -f $MODULE_JAR ]; then
127        echo "  $MODULE_JAR"
128        JARS="$JARS $MODULE_JAR"
129      fi
130    done
131
132    if [[ $SURFACE == "system-server" ]]; then
133      # Add all the system-server jars to the list of jars to merge.
134      for MODULE in ${SYSTEM_SERVER_MODULES[@]}
135      do
136        MODULE_JAR=$SURFACE_DIR/$MODULE
137        if [ -f $MODULE_JAR ]; then
138          echo "  $MODULE_JAR"
139          JARS="$JARS $MODULE_JAR"
140        fi
141      done
142    fi
143
144    # Merge all the zips ignoring duplicates (should only be
145    # META-INF/MANIFEST.MF) created a sorted (-s) jar (-j).
146    merge_zips -ignore-duplicates -j -s $NEW_JAR $JARS
147
148    README=$SURFACE_DIR/README.md
149    cat > $README <<EOF
150## Updated since finalization
151
152The android-plus-updatable.jar has been added to this directory after
153finalization as the android.jar in this directory does not include updatable
154modules. That is because doing so in the source would lead to dependency cycles
155and the prebuilts have to match the source structure so that apps can build
156against either prebuilts or sources.
157
158The lack of updatable modules in android.jar caused problems for the
159api-version.xml generation as that requires a single jar containing all the
160APIs for each surface of each API version. See b/337836752 for more
161information.
162EOF
163
164    # Adding the new files to git.
165    (cd $SOURCE_DIR; git add ${NEW_JAR#$SOURCE_DIR/} ${README#$SOURCE_DIR/})
166
167  done
168done
169