Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e33cbeb authored by Zhomart Mukhamejanov's avatar Zhomart Mukhamejanov Committed by Gerrit Code Review
Browse files

Merge "Add PrepareUpdateService."

parents a8d712ec bc077753
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".services.PrepareStreamingService"/>
        <service android:name=".services.PrepareUpdateService"/>
    </application>

</manifest>
+3 −3
Original line number Diff line number Diff line
@@ -220,7 +220,7 @@ privileged system app, so it's granted the required permissions to access
- [x] Add Sample app update state (separate from update_engine status)
- [x] Add smart update completion detection using onStatusUpdate
- [x] Add pause/resume demo
- [x] Verify system partition checksum for package
- [-] Verify system partition checksum for package


## Running tests
@@ -235,8 +235,8 @@ privileged system app, so it's granted the required permissions to access
5. Run a test file
   ```
   adb shell am instrument \
     -w com.example.android.systemupdatersample.tests/android.support.test.runner.AndroidJUnitRunner \
     -c com.example.android.systemupdatersample.util.PayloadSpecsTest
     -w -e class com.example.android.systemupdatersample.UpdateManagerTest#applyUpdate_appliesPayloadToUpdateEngine \
     com.example.android.systemupdatersample.tests/android.support.test.runner.AndroidJUnitRunner
   ```


+30 −49
Original line number Diff line number Diff line
@@ -17,19 +17,18 @@
package com.example.android.systemupdatersample;

import android.content.Context;
import android.os.Handler;
import android.os.UpdateEngine;
import android.os.UpdateEngineCallback;
import android.util.Log;

import com.example.android.systemupdatersample.services.PrepareStreamingService;
import com.example.android.systemupdatersample.util.PayloadSpecs;
import com.example.android.systemupdatersample.services.PrepareUpdateService;
import com.example.android.systemupdatersample.util.UpdateEngineErrorCodes;
import com.example.android.systemupdatersample.util.UpdateEngineProperties;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.AtomicDouble;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -50,11 +49,10 @@ public class UpdateManager {
    private static final String TAG = "UpdateManager";

    /** HTTP Header: User-Agent; it will be sent to the server when streaming the payload. */
    private static final String HTTP_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
    static final String HTTP_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36";

    private final UpdateEngine mUpdateEngine;
    private final PayloadSpecs mPayloadSpecs;

    private AtomicInteger mUpdateEngineStatus =
            new AtomicInteger(UpdateEngine.UpdateStatusConstants.IDLE);
@@ -84,9 +82,15 @@ public class UpdateManager {
    private final UpdateManager.UpdateEngineCallbackImpl
            mUpdateEngineCallback = new UpdateManager.UpdateEngineCallbackImpl();

    public UpdateManager(UpdateEngine updateEngine, PayloadSpecs payloadSpecs) {
    private final Handler mHandler;

    /**
     * @param updateEngine UpdateEngine instance.
     * @param handler      Handler for {@link PrepareUpdateService} intent service.
     */
    public UpdateManager(UpdateEngine updateEngine, Handler handler) {
        this.mUpdateEngine = updateEngine;
        this.mPayloadSpecs = payloadSpecs;
        this.mHandler = handler;
    }

    /**
@@ -293,45 +297,17 @@ public class UpdateManager {
            mManualSwitchSlotRequired.set(false);
        }

        if (config.getInstallType() == UpdateConfig.AB_INSTALL_TYPE_NON_STREAMING) {
            applyAbNonStreamingUpdate(config);
        } else {
            applyAbStreamingUpdate(context, config);
        }
    }

    private void applyAbNonStreamingUpdate(UpdateConfig config)
            throws UpdaterState.InvalidTransitionException {
        UpdateData.Builder builder = UpdateData.builder()
                .setExtraProperties(prepareExtraProperties(config));

        try {
            builder.setPayload(mPayloadSpecs.forNonStreaming(config.getUpdatePackageFile()));
        } catch (IOException e) {
            Log.e(TAG, "Error creating payload spec", e);
            setUpdaterState(UpdaterState.ERROR);
            return;
        }
        updateEngineApplyPayload(builder.build());
    }

    private void applyAbStreamingUpdate(Context context, UpdateConfig config) {
        UpdateData.Builder builder = UpdateData.builder()
                .setExtraProperties(prepareExtraProperties(config));

        Log.d(TAG, "Starting PrepareStreamingService");
        PrepareStreamingService.startService(context, config, (code, payloadSpec) -> {
            if (code == PrepareStreamingService.RESULT_CODE_SUCCESS) {
                builder.setPayload(payloadSpec);
                builder.addExtraProperty("USER_AGENT=" + HTTP_USER_AGENT);
                config.getAbConfig()
                        .getAuthorization()
                        .ifPresent(s -> builder.addExtraProperty("AUTHORIZATION=" + s));
                updateEngineApplyPayload(builder.build());
            } else {
                Log.e(TAG, "PrepareStreamingService failed, result code is " + code);
        Log.d(TAG, "Starting PrepareUpdateService");
        PrepareUpdateService.startService(context, config, mHandler, (code, payloadSpec) -> {
            if (code != PrepareUpdateService.RESULT_CODE_SUCCESS) {
                Log.e(TAG, "PrepareUpdateService failed, result code is " + code);
                setUpdaterStateSilent(UpdaterState.ERROR);
                return;
            }
            updateEngineApplyPayload(UpdateData.builder()
                    .setExtraProperties(prepareExtraProperties(config))
                    .setPayload(payloadSpec)
                    .build());
        });
    }

@@ -343,6 +319,12 @@ public class UpdateManager {
            // User will enable it manually by clicking "Switch Slot" button on the screen.
            extraProperties.add(UpdateEngineProperties.PROPERTY_DISABLE_SWITCH_SLOT_ON_REBOOT);
        }
        if (config.getInstallType() == UpdateConfig.AB_INSTALL_TYPE_STREAMING) {
            extraProperties.add("USER_AGENT=" + HTTP_USER_AGENT);
            config.getAbConfig()
                    .getAuthorization()
                    .ifPresent(s -> extraProperties.add("AUTHORIZATION=" + s));
        }
        return extraProperties;
    }

@@ -555,7 +537,6 @@ public class UpdateManager {
    }

    /**
     *
     * Contains update data - PayloadSpec and extra properties list.
     *
     * <p>{@code mPayload} contains url, offset and size to {@code PAYLOAD_BINARY_FILE_NAME}.
+31 −24
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.RecoverySystem;
import android.os.ResultReceiver;
import android.os.UpdateEngine;
import android.util.Log;

import com.example.android.systemupdatersample.PayloadSpec;
@@ -49,10 +50,10 @@ import java.util.Optional;
 * without downloading the whole package. And it constructs {@link PayloadSpec}.
 * All this work required to install streaming A/B updates.
 *
 * PrepareStreamingService runs on it's own thread. It will notify activity
 * PrepareUpdateService runs on it's own thread. It will notify activity
 * using interface {@link UpdateResultCallback} when update is ready to install.
 */
public class PrepareStreamingService extends IntentService {
public class PrepareUpdateService extends IntentService {

    /**
     * UpdateResultCallback result codes.
@@ -61,22 +62,27 @@ public class PrepareStreamingService extends IntentService {
    public static final int RESULT_CODE_ERROR = 1;

    /**
     * This interface is used to send results from {@link PrepareStreamingService} to
     * Extra params that will be sent to IntentService.
     */
    public static final String EXTRA_PARAM_CONFIG = "config";
    public static final String EXTRA_PARAM_RESULT_RECEIVER = "result-receiver";

    /**
     * This interface is used to send results from {@link PrepareUpdateService} to
     * {@code MainActivity}.
     */
    public interface UpdateResultCallback {

        /**
         * Invoked when files are downloaded and payload spec is constructed.
         *
         * @param resultCode result code, values are defined in {@link PrepareStreamingService}
         * @param resultCode  result code, values are defined in {@link PrepareUpdateService}
         * @param payloadSpec prepared payload spec for streaming update
         */
        void onReceiveResult(int resultCode, PayloadSpec payloadSpec);
    }

    /**
     * Starts PrepareStreamingService.
     * Starts PrepareUpdateService.
     *
     * @param context        application context
     * @param config         update config
@@ -84,26 +90,21 @@ public class PrepareStreamingService extends IntentService {
     */
    public static void startService(Context context,
            UpdateConfig config,
            Handler handler,
            UpdateResultCallback resultCallback) {
        Log.d(TAG, "Starting PrepareStreamingService");
        ResultReceiver receiver = new CallbackResultReceiver(new Handler(), resultCallback);
        Intent intent = new Intent(context, PrepareStreamingService.class);
        Log.d(TAG, "Starting PrepareUpdateService");
        ResultReceiver receiver = new CallbackResultReceiver(handler, resultCallback);
        Intent intent = new Intent(context, PrepareUpdateService.class);
        intent.putExtra(EXTRA_PARAM_CONFIG, config);
        intent.putExtra(EXTRA_PARAM_RESULT_RECEIVER, receiver);
        context.startService(intent);
    }

    public PrepareStreamingService() {
    public PrepareUpdateService() {
        super(TAG);
    }

    private static final String TAG = "PrepareStreamingService";

    /**
     * Extra params that will be sent from Activity to IntentService.
     */
    private static final String EXTRA_PARAM_CONFIG = "config";
    private static final String EXTRA_PARAM_RESULT_RECEIVER = "result-receiver";
    private static final String TAG = "PrepareUpdateService";

    /**
     * The files that should be downloaded before streaming.
@@ -117,6 +118,7 @@ public class PrepareStreamingService extends IntentService {
            );

    private final PayloadSpecs mPayloadSpecs = new PayloadSpecs();
    private final UpdateEngine mUpdateEngine = new UpdateEngine();

    @Override
    protected void onHandleIntent(Intent intent) {
@@ -142,6 +144,10 @@ public class PrepareStreamingService extends IntentService {
    private PayloadSpec execute(UpdateConfig config)
            throws IOException, PreparationFailedException {

        if (config.getInstallType() == UpdateConfig.AB_INSTALL_TYPE_NON_STREAMING) {
            return mPayloadSpecs.forNonStreaming(config.getUpdatePackageFile());
        }

        downloadPreStreamingFiles(config, OTA_PACKAGE_DIR);

        Optional<UpdateConfig.PackageFile> payloadBinary =
@@ -176,6 +182,7 @@ public class PrepareStreamingService extends IntentService {
     * Downloads files defined in {@link UpdateConfig#getAbConfig()}
     * and exists in {@code PRE_STREAMING_FILES_SET}, and put them
     * in directory {@code dir}.
     *
     * @throws IOException when can't download a file
     */
    private void downloadPreStreamingFiles(UpdateConfig config, String dir)
@@ -212,7 +219,7 @@ public class PrepareStreamingService extends IntentService {
    }

    /**
     * Used by {@link PrepareStreamingService} to pass {@link PayloadSpec}
     * Used by {@link PrepareUpdateService} to pass {@link PayloadSpec}
     * to {@link UpdateResultCallback#onReceiveResult}.
     */
    private static class CallbackResultReceiver extends ResultReceiver {
+2 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.app.AlertDialog;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.UpdateEngine;
import android.util.Log;
import android.view.View;
@@ -34,7 +35,6 @@ import com.example.android.systemupdatersample.R;
import com.example.android.systemupdatersample.UpdateConfig;
import com.example.android.systemupdatersample.UpdateManager;
import com.example.android.systemupdatersample.UpdaterState;
import com.example.android.systemupdatersample.util.PayloadSpecs;
import com.example.android.systemupdatersample.util.UpdateConfigs;
import com.example.android.systemupdatersample.util.UpdateEngineErrorCodes;
import com.example.android.systemupdatersample.util.UpdateEngineStatuses;
@@ -67,7 +67,7 @@ public class MainActivity extends Activity {
    private List<UpdateConfig> mConfigs;

    private final UpdateManager mUpdateManager =
            new UpdateManager(new UpdateEngine(), new PayloadSpecs());
            new UpdateManager(new UpdateEngine(), new Handler());

    @Override
    protected void onCreate(Bundle savedInstanceState) {
Loading