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

Commit c5756a18 authored by Allen Su's avatar Allen Su
Browse files

Implement B&R for system gender

Bug: 328586505
Test: atest SystemBackupAgentTest.java, atest GrammaticalInflectionBackupTest.java
Change-Id: Ie2217b6f534ca0db7a8656fa33a977e99f7ca0f2
parent ef54218e
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -34,10 +34,11 @@ import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;
import com.google.android.collect.Sets;

import com.android.server.backup.Flags;

import com.google.android.collect.Sets;

import java.io.File;
import java.io.IOException;
import java.util.Set;
@@ -64,6 +65,7 @@ public class SystemBackupAgent extends BackupAgentHelper {
    private static final String APP_LOCALES_HELPER = "app_locales";
    private static final String APP_GENDER_HELPER = "app_gender";
    private static final String COMPANION_HELPER = "companion";
    private static final String SYSTEM_GENDER_HELPER = "system_gender";

    // These paths must match what the WallpaperManagerService uses.  The leaf *_FILENAME
    // are also used in the full-backup file format, so must not change unless steps are
@@ -99,7 +101,9 @@ public class SystemBackupAgent extends BackupAgentHelper {
                    NOTIFICATION_HELPER,
                    SYNC_SETTINGS_HELPER,
                    APP_LOCALES_HELPER,
                    COMPANION_HELPER);
                    COMPANION_HELPER,
                    APP_GENDER_HELPER,
                    SYSTEM_GENDER_HELPER);

    /** Helpers that are enabled for full, non-system users. */
    private static final Set<String> sEligibleHelpersForNonSystemUser =
@@ -139,6 +143,8 @@ public class SystemBackupAgent extends BackupAgentHelper {
        addHelperIfEligibleForUser(APP_GENDER_HELPER,
                new AppGrammaticalGenderBackupHelper(mUserId));
        addHelperIfEligibleForUser(COMPANION_HELPER, new CompanionBackupHelper(mUserId));
        addHelperIfEligibleForUser(SYSTEM_GENDER_HELPER,
                new SystemGrammaticalGenderBackupHelper(mUserId));
    }

    @Override
+66 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.backup;

import static android.app.backup.BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED;

import android.annotation.UserIdInt;
import android.app.backup.BackupDataOutput;
import android.app.backup.BlobBackupHelper;
import android.os.ParcelFileDescriptor;

import com.android.server.LocalServices;
import com.android.server.grammaticalinflection.GrammaticalInflectionManagerInternal;

public class SystemGrammaticalGenderBackupHelper extends BlobBackupHelper {
    private static final int BLOB_VERSION = 1;
    private static final String KEY_SYSTEM_GENDER = "system_gender";

    private final @UserIdInt int mUserId;
    private final GrammaticalInflectionManagerInternal mGrammarInflectionManagerInternal;

    public SystemGrammaticalGenderBackupHelper(int userId) {
        super(BLOB_VERSION, KEY_SYSTEM_GENDER);
        mUserId = userId;
        mGrammarInflectionManagerInternal = LocalServices.getService(
                GrammaticalInflectionManagerInternal.class);
    }

    @Override
    public void performBackup(ParcelFileDescriptor oldStateFd, BackupDataOutput data,
            ParcelFileDescriptor newStateFd) {
        // Only backup the gender data if e2e encryption is present
        if ((data.getTransportFlags() & FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED) == 0) {
            return;
        }

        super.performBackup(oldStateFd, data, newStateFd);
    }

    @Override
    protected byte[] getBackupPayload(String key) {
        return KEY_SYSTEM_GENDER.equals(key) && mGrammarInflectionManagerInternal != null
                ? mGrammarInflectionManagerInternal.getSystemBackupPayload(mUserId) : null;
    }

    @Override
    protected void applyRestoredPayload(String key, byte[] payload) {
        if (KEY_SYSTEM_GENDER.equals(key) && mGrammarInflectionManagerInternal != null) {
            mGrammarInflectionManagerInternal.applyRestoredSystemPayload(payload, mUserId);
        }
    }
}
+34 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.grammaticalinflection;

import android.app.backup.BackupManager;
import android.content.AttributionSource;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -30,6 +31,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
import java.time.Clock;
import java.time.Duration;
import java.util.HashMap;
@@ -47,6 +49,7 @@ public class GrammaticalInflectionBackupHelper {
    private final PackageManager mPackageManager;
    private final GrammaticalInflectionService mGrammaticalGenderService;
    private final Clock mClock;
    private final AttributionSource mAttributionSource;

    static class StagedData {
        final long mCreationTimeMillis;
@@ -58,8 +61,9 @@ public class GrammaticalInflectionBackupHelper {
        }
    }

    public GrammaticalInflectionBackupHelper(GrammaticalInflectionService grammaticalGenderService,
            PackageManager packageManager) {
    public GrammaticalInflectionBackupHelper(AttributionSource attributionSource,
            GrammaticalInflectionService grammaticalGenderService, PackageManager packageManager) {
        mAttributionSource = attributionSource;
        mGrammaticalGenderService = grammaticalGenderService;
        mPackageManager = packageManager;
        mClock = Clock.systemUTC();
@@ -115,6 +119,23 @@ public class GrammaticalInflectionBackupHelper {
        }
    }

    /**
     * Returns the system-gender to be backed up as a data-blob.
     */
    public byte[] getSystemBackupPayload(int userId) {
        int gender = mGrammaticalGenderService.getSystemGrammaticalGender(mAttributionSource,
                userId);
        return intToByteArray(gender);
    }

    /**
     * Restores the system-gender that were previously backed up.
     */
    public void applyRestoredSystemPayload(byte[] payload, int userId) {
        int gender = convertByteArrayToInt(payload);
        mGrammaticalGenderService.setSystemWideGrammaticalGender(gender, userId);
    }

    private boolean hasSetBeforeRestoring(String pkgName, int userId) {
        return mGrammaticalGenderService.getApplicationGrammaticalGender(pkgName, userId)
                != Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED;
@@ -157,6 +178,17 @@ public class GrammaticalInflectionBackupHelper {
        }
    }

    private byte[] intToByteArray(final int gender) {
        ByteBuffer bb = ByteBuffer.allocate(4);
        bb.putInt(gender);
        return bb.array();
    }

    private int convertByteArrayToInt(byte[] intBytes) {
        ByteBuffer byteBuffer = ByteBuffer.wrap(intBytes);
        return byteBuffer.getInt();
    }

    private HashMap<String, Integer> readFromByteArray(byte[] payload) {
        HashMap<String, Integer> data = new HashMap<>();

+11 −0
Original line number Diff line number Diff line
@@ -62,5 +62,16 @@ public abstract class GrammaticalInflectionManagerInternal {
     * Whether the package can get the system grammatical gender or not.
     */
    public abstract boolean canGetSystemGrammaticalGender(int uid, @Nullable String packageName);


    /**
     * Returns the system-gender to be backed up as a data-blob.
     */
    public abstract @Nullable byte[] getSystemBackupPayload(int userId);

    /**
     * Restores the system-gender that were previously backed up.
     */
    public abstract void applyRestoredSystemPayload(byte[] payload, int userId);
}
+15 −1
Original line number Diff line number Diff line
@@ -102,7 +102,8 @@ public class GrammaticalInflectionService extends SystemService {
        mContext = context;
        mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
        mBackupHelper = new GrammaticalInflectionBackupHelper(this, context.getPackageManager());
        mBackupHelper = new GrammaticalInflectionBackupHelper(mContext.getAttributionSource(), this,
                context.getPackageManager());
        mBinderService = new GrammaticalInflectionBinderService();
        mPermissionManager = context.getSystemService(PermissionManager.class);
    }
@@ -175,6 +176,18 @@ public class GrammaticalInflectionService extends SystemService {
            mBackupHelper.stageAndApplyRestoredPayload(payload, userId);
        }

        @Override
        @Nullable
        public byte[] getSystemBackupPayload(int userId) {
            isCallerAllowed();
            return mBackupHelper.getSystemBackupPayload(userId);
        }

        @Override
        public void applyRestoredSystemPayload(byte[] payload, int userId) {
            mBackupHelper.applyRestoredSystemPayload(payload, userId);
        }

        @Override
        public int getSystemGrammaticalGender(int userId) {
            return checkSystemTermsOfAddressIsEnabled()
@@ -290,6 +303,7 @@ public class GrammaticalInflectionService extends SystemService {
                    userId,
                    grammaticalGender != GRAMMATICAL_GENDER_NOT_SPECIFIED,
                    preValue != GRAMMATICAL_GENDER_NOT_SPECIFIED);
            GrammaticalInflectionBackupHelper.notifyBackupManager();
        } catch (RemoteException e) {
            Log.w(TAG, "Can not update configuration", e);
        }
Loading