13aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel/* 23aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * Copyright (C) 2014 The Android Open Source Project 33aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * 43aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * Licensed under the Apache License, Version 2.0 (the "License"); 53aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * you may not use this file except in compliance with the License. 63aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * You may obtain a copy of the License at 73aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * 83aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * http://www.apache.org/licenses/LICENSE-2.0 93aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * 103aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * Unless required by applicable law or agreed to in writing, software 113aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * distributed under the License is distributed on an "AS IS" BASIS, 123aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * See the License for the specific language governing permissions and 143aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * limitations under the License. 153aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel */ 163aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 173aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Rousselpackage com.android.framework.multidexlegacytestservices; 183aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 193aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Rousselimport android.app.Service; 203aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Rousselimport android.content.Context; 213aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Rousselimport android.content.Intent; 223aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Rousselimport android.os.IBinder; 23c7bf3e206ae16feb9202f58a63dd2adbf16be004Alan Viveretteimport androidx.multidex.MultiDex; 243aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Rousselimport android.util.Log; 253aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 263aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Rousselimport java.io.File; 273aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Rousselimport java.io.IOException; 283aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Rousselimport java.io.RandomAccessFile; 293aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 303aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel/** 313aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * Empty service for testing legacy multidex. Access more than 64k methods but some are required at 323aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel * init, some only at verification and others during execution. 333aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel */ 34affa8a4736177f62911c9e0fe9280247c823e8bfYohann Rousselpublic abstract class AbstractService extends Service implements Runnable { 353aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel private final String TAG = "MultidexLegacyTestService" + getId(); 363aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 373aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel private int instanceFieldNotInited; 383aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel private int instanceFieldInited = 393aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big043().get43(); 403aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel private static int staticField = 413aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big044().get44(); 423aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 433aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel public AbstractService() { 443aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel instanceFieldNotInited = new com.android.framework.multidexlegacytestservices.manymethods.Big042().get42(); 453aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel } 463aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 473aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel @Override 483aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel public void onCreate() { 493aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel Log.i(TAG, "onCreate"); 50affa8a4736177f62911c9e0fe9280247c823e8bfYohann Roussel new Thread(this).start(); 51affa8a4736177f62911c9e0fe9280247c823e8bfYohann Roussel 52affa8a4736177f62911c9e0fe9280247c823e8bfYohann Roussel } 53affa8a4736177f62911c9e0fe9280247c823e8bfYohann Roussel 54affa8a4736177f62911c9e0fe9280247c823e8bfYohann Roussel @Override 55affa8a4736177f62911c9e0fe9280247c823e8bfYohann Roussel public void run() { 563aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel Context applicationContext = getApplicationContext(); 573aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel File resultFile = new File(applicationContext.getFilesDir(), getId()); 583aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel try { 593aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel // Append a constant value in result file, if services crashed and is relaunched, size 603aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel // of the result file will be too big. 613aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel RandomAccessFile raf = new RandomAccessFile(resultFile, "rw"); 623aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel raf.seek(raf.length()); 63493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel if (raf.length() == 0) { 64493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel Log.i(TAG, "Writing 0x42434445 at " + raf.length() + " in " + resultFile.getPath()); 65493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel raf.writeInt(0x42434445); 66493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel } else { 67493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel Log.w(TAG, "Service was restarted appending 0x42434445 twice at " + raf.length() 68493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel + " in " + resultFile.getPath()); 69493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel raf.writeInt(0x42434445); 70493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel raf.writeInt(0x42434445); 71493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel } 723aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel raf.close(); 73493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel MultiDex.install(applicationContext); 74493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel Log.i(TAG, "Multi dex installation done."); 753aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 76493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel int value = getValue(); 77493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel Log.i(TAG, "Saving the result (" + value + ") to " + resultFile.getPath()); 783aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel // Append the check value in result file, keeping the constant values already written. 79493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel raf = new RandomAccessFile(resultFile, "rw"); 803aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel raf.seek(raf.length()); 813aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel Log.i(TAG, "Writing result at " + raf.length() + " in " + resultFile.getPath()); 823aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel raf.writeInt(value); 833aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel raf.close(); 843aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel } catch (IOException e) { 85493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel throw new AssertionError(e); 86493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel } finally { 87493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel try { 88493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel // Writing end of processing flags, the existence of the file is the criteria 89493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel RandomAccessFile raf = new RandomAccessFile( 90493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel new File(applicationContext.getFilesDir(), getId() + ".complete"), "rw"); 91493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel Log.i(TAG, "creating complete file " + resultFile.getPath()); 92493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel raf.writeInt(0x32333435); 93493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel raf.close(); 94493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel } catch (IOException e) { 95493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel e.printStackTrace(); 96493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel } 973aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel } 983aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel } 993aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 1003aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel @Override 1013aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel public int onStartCommand(Intent intent, int flags, int startId) { 1023aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel Log.i("Service" + getId(), "Received start id " + startId + ": " + intent); 1033aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel // We want this service to continue running until it is explicitly 1043aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel // stopped, so return sticky. 1053aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel return START_STICKY; 1063aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel } 1073aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 1083aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel private String getId() { 1093aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel return this.getClass().getSimpleName(); 1103aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel } 1113aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 1123aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel @Override 1133aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel public void onDestroy() { 1143aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel } 1153aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 1163aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel @Override 1173aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel public IBinder onBind(Intent intent) { 1183aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel return null; 1193aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel } 1203aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 1213aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel public int getValue() { 1223aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel int intermediate = -1; 1233aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel try { 1243aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel intermediate = ReflectIntermediateClass.get(45, 80, 20 /* 5 seems enough on a nakasi, 1253aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel using 20 to get some margin */); 1263aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel } catch (Exception e) { 127493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel throw new AssertionError(e); 1283aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel } 129493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel int value = 130493cebd02538adf347413450238bb1f3f7a0d541Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big001().get1() + 1313aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big002().get2() + 1323aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big003().get3() + 1333aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big004().get4() + 1343aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big005().get5() + 1353aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big006().get6() + 1363aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big007().get7() + 1373aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big008().get8() + 1383aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big009().get9() + 1393aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big010().get10() + 1403aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big011().get11() + 1413aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big012().get12() + 1423aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big013().get13() + 1433aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big014().get14() + 1443aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big015().get15() + 1453aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big016().get16() + 1463aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big017().get17() + 1473aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big018().get18() + 1483aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big019().get19() + 1493aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big020().get20() + 1503aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big021().get21() + 1513aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big022().get22() + 1523aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big023().get23() + 1533aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big024().get24() + 1543aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big025().get25() + 1553aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big026().get26() + 1563aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big027().get27() + 1573aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big028().get28() + 1583aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big029().get29() + 1593aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big030().get30() + 1603aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big031().get31() + 1613aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big032().get32() + 1623aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big033().get33() + 1633aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big034().get34() + 1643aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big035().get35() + 1653aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big036().get36() + 1663aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big037().get37() + 1673aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big038().get38() + 1683aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big039().get39() + 1693aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big040().get40() + 1703aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel new com.android.framework.multidexlegacytestservices.manymethods.Big041().get41() + 1713aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel instanceFieldNotInited + 1723aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel instanceFieldInited + 1733aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel staticField + 1743aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel intermediate; 1753aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel return value; 1763aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel } 1773aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel 1783aac33e7262dc53d878b9c7d44c3cfd31619d128Yohann Roussel} 179