1 /*
2  * Copyright (C) 2018 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 
17 package com.android.cts.install.lib.testapp;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.res.Resources;
23 
24 import java.io.File;
25 import java.io.FileNotFoundException;
26 import java.io.IOException;
27 import java.io.PrintWriter;
28 import java.util.Scanner;
29 
30 /**
31  * A broadcast receiver to check for and update user app data version
32  * compatibility.
33  */
34 public class ProcessUserData extends BroadcastReceiver {
35 
36     /**
37      * Exception thrown in case of issue with user data.
38      */
39     public static class UserDataException extends Exception {
UserDataException(String message)40         public UserDataException(String message) {
41             super(message);
42         }
43 
UserDataException(String message, Throwable cause)44         public UserDataException(String message, Throwable cause) {
45            super(message, cause);
46         }
47     }
48 
49     @Override
onReceive(Context context, Intent intent)50     public void onReceive(Context context, Intent intent) {
51         try {
52             processUserData(context);
53             setResultCode(1);
54         } catch (UserDataException e) {
55             setResultCode(0);
56             setResultData(e.getMessage());
57         }
58     }
59 
60     /**
61      * Update the app's user data version to match the app version.
62      *
63      * @param context The application context.
64      * @throws UserDataException in case of problems with app user data.
65      */
processUserData(Context context)66     public void processUserData(Context context) throws UserDataException {
67         Resources res = context.getResources();
68         String packageName = context.getPackageName();
69 
70         int appVersionId = res.getIdentifier("app_version", "integer", packageName);
71         int appVersion = res.getInteger(appVersionId);
72 
73         int splitVersionId = res.getIdentifier("split_version", "integer", packageName);
74         int splitVersion = res.getInteger(splitVersionId);
75 
76         // Make sure the app version and split versions are compatible.
77         if (appVersion != splitVersion) {
78             throw new UserDataException("Split version " + splitVersion
79                     + " does not match app version " + appVersion);
80         }
81 
82         // Read the version of the app's user data and ensure it is compatible
83         // with our version of the application.
84         File versionFile = new File(context.getFilesDir(), "version.txt");
85         try {
86             Scanner s = new Scanner(versionFile);
87             int userDataVersion = s.nextInt();
88             s.close();
89 
90             if (userDataVersion > appVersion) {
91                 throw new UserDataException("User data is from version " + userDataVersion
92                         + ", which is not compatible with this version " + appVersion
93                         + " of the RollbackTestApp");
94             }
95         } catch (FileNotFoundException e) {
96             // No problem. This is a fresh install of the app or the user data
97             // has been wiped.
98         }
99 
100         // Record the current version of the app in the user data.
101         try {
102             PrintWriter pw = new PrintWriter(versionFile);
103             pw.println(appVersion);
104             pw.close();
105         } catch (IOException e) {
106             throw new UserDataException("Unable to write user data.", e);
107         }
108     }
109 }
110