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

Commit f8f5f46f authored by Doris Ling's avatar Doris Ling Committed by Android (Google) Code Review
Browse files

Merge "Revert "Get intent for backup settings from backup transport.""

parents f75b6518 ff3db157
Loading
Loading
Loading
Loading
+32 −20
Original line number Diff line number Diff line
@@ -17,13 +17,19 @@
package com.android.settings;

import android.app.Activity;
import android.content.ComponentName;
import android.app.backup.BackupManager;
import android.app.backup.IBackupManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;

import com.android.settings.Settings.PrivacySettingsActivity;
import com.android.settings.R;

import java.net.URISyntaxException;

/**
 * A trampoline activity used to launch the configured Backup activity.
@@ -36,24 +42,30 @@ public class BackupSettingsActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        BackupSettingsHelper backupHelper = new BackupSettingsHelper();
        if (backupHelper.isIntentProvidedByTransport(getPackageManager())) {
            Intent intent = backupHelper.getIntentForBackupSettings();
            if (intent != null) {
        String backup = getResources().getString(R.string.config_backup_settings_intent);
        if (!TextUtils.isEmpty(backup)) {
            try {
                Intent intent = Intent.parseUri(backup, 0);
                if (intent.resolveActivity(getPackageManager()) != null) {
                    // use startActivityForResult to let the activity check the caller signature
                startActivityForResult(intent, -1);
                    IBackupManager bmgr = IBackupManager.Stub.asInterface(
                            ServiceManager.getService(Context.BACKUP_SERVICE));
                    boolean backupOkay;
                    try {
                        backupOkay = bmgr.isBackupServiceActive(UserHandle.myUserId());
                    } catch (Exception e) {
                        // things go wrong talking to the backup system => ignore and
                        // pass the default 'false' as the "backup is a thing?" state.
                        backupOkay = false;
                    }
                    intent.putExtra(BackupManager.EXTRA_BACKUP_SERVICES_AVAILABLE, backupOkay);
                    startActivityForResult(intent, -1);
                } else {
            // This should never happen, because isIntentProvidedByTransport() is called before
            // starting this activity.
            Log.e(TAG, "Backup transport has not provided an intent"
                    + " or the component for the intent is not found!");
            getPackageManager().setComponentEnabledSetting(
                    new ComponentName(getPackageName(), PrivacySettingsActivity.class.getName()),
                    PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                    PackageManager.DONT_KILL_APP);
            startActivityForResult(new Intent(this, PrivacySettingsActivity.class), -1);
                    Log.e(TAG, "Backup component not found!");
                }
            } catch (URISyntaxException e) {
                Log.e(TAG, "Invalid backup component URI!", e);
            }
        }
        finish();
    }
+0 −103
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.settings;


import android.app.backup.BackupManager;
import android.app.backup.BackupTransport;
import android.app.backup.IBackupManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;

/**
 * Helper class for {@link BackupSettingsActivity} that interacts with {@link IBackupManager}.
 */
public class BackupSettingsHelper {
    private static final String TAG = "BackupSettingsHelper";

    private IBackupManager mBackupManager = IBackupManager.Stub.asInterface(
            ServiceManager.getService(Context.BACKUP_SERVICE));


    /**
     * Gets the intent from Backup transport and adds the extra depending on whether the user has
     * rights to see backup settings.
     *
     * @return Intent to launch Backup settings provided by the Backup transport.
     */
    public Intent getIntentForBackupSettings() {
        Intent intent = getIntentFromBackupTransport();
        if (intent != null) {
            intent.putExtra(BackupManager.EXTRA_BACKUP_SERVICES_AVAILABLE, isBackupServiceActive());
        }
        return intent;
    }


    /**
     * Checks if the transport provided the intent to launch the backup settings and if that
     * intent resolves to an activity.
     */
    public boolean isIntentProvidedByTransport(PackageManager packageManager) {
        Intent intent = getIntentFromBackupTransport();
        return intent != null && intent.resolveActivity(packageManager) != null;
    }

    /**
     * Gets an intent to launch the backup settings from the current transport using
     * {@link BackupTransport#dataManagementIntent()} API.
     *
     * @return intent provided by transport or null if no intent was provided.
     */
    private Intent getIntentFromBackupTransport() {
        try {
            Intent intent =
                    mBackupManager.getDataManagementIntent(mBackupManager.getCurrentTransport());
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                if (intent != null) {
                    Log.d(TAG, "Parsed intent from backup transport: " + intent.toString());
                } else {
                    Log.d(TAG, "Received a null intent from backup transport");
                }
            }
            return intent;
        } catch (RemoteException e) {
            Log.e(TAG, "Error getting data management intent", e);
        }
        return null;
    }

    /** Checks if backup service is enabled for this user. */
    private boolean isBackupServiceActive() {
        boolean backupOkay;
        try {
            backupOkay = mBackupManager.isBackupServiceActive(UserHandle.myUserId());
        } catch (Exception e) {
            // things go wrong talking to the backup system => ignore and
            // pass the default 'false' as the "backup is a thing?" state.
            backupOkay = false;
        }
        return backupOkay;
    }
}
+14 −14
Original line number Diff line number Diff line
@@ -33,8 +33,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.nfc.NfcAdapter;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
@@ -967,27 +965,29 @@ public class SettingsActivity extends SettingsDrawerActivity
            }
        }

        // Check if the backup transport has provided an intent to launch the backup settings.
        BackupSettingsHelper backupHelper = new BackupSettingsHelper();
        boolean useDefaultBackup = !backupHelper.isIntentProvidedByTransport(getPackageManager());
        if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
            Log.v(LOG_TAG, "Enabling default backup settings page: " + useDefaultBackup);
        }

        String backupIntent = getResources().getString(R.string.config_backup_settings_intent);
        boolean useDefaultBackup = TextUtils.isEmpty(backupIntent);
        setTileEnabled(new ComponentName(packageName,
                Settings.PrivacySettingsActivity.class.getName()), useDefaultBackup, isAdmin);
        setTileEnabled(new ComponentName(packageName,
                        "com.android.settings.PrivacyDashboardAlias"),
                useDefaultBackup, isAdmin);

        // Enable/disable BackupSettingsActivity and its alias.
        if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
            Log.v(LOG_TAG, "Enabling transport provided backup settings: " + !useDefaultBackup);
        boolean hasBackupActivity = false;
        if (!useDefaultBackup) {
            try {
                Intent intent = Intent.parseUri(backupIntent, 0);
                hasBackupActivity = !getPackageManager().queryIntentActivities(intent, 0).isEmpty();
            } catch (URISyntaxException e) {
                Log.e(LOG_TAG, "Invalid backup intent URI!", e);
            }
        }

        // Enable/disable BackupSettingsActivity and its alias.
        setTileEnabled(new ComponentName(packageName,
                BackupSettingsActivity.class.getName()), !useDefaultBackup, isAdmin);
                BackupSettingsActivity.class.getName()), hasBackupActivity, isAdmin);
        setTileEnabled(new ComponentName(packageName,
                "com.android.settings.BackupResetDashboardAlias"), !useDefaultBackup, isAdmin);
                "com.android.settings.BackupResetDashboardAlias"), hasBackupActivity, isAdmin);

        setTileEnabled(new ComponentName(packageName,
                Settings.EnterprisePrivacySettingsActivity.class.getName()),
+0 −188
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.settings;

import android.app.backup.BackupManager;
import android.app.backup.IBackupManager;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.RemoteException;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;




@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
        shadows = {BackupSettingsHelperTest.ShadowBackupManagerStub.class})
public class BackupSettingsHelperTest {

    private BackupSettingsHelper mBackupSettingsHelper;

    @Mock
    private static IBackupManager mBackupManager;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        when(mBackupManager.getCurrentTransport()).thenReturn("test_transport");
        mBackupSettingsHelper = new BackupSettingsHelper();
    }

    @Test
    public void testGetIntentFromBackupTransport() throws Exception {
        Intent intent = new Intent();

        when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent);

        Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettings();

        verify(mBackupManager).getDataManagementIntent(anyString());
    }

    @Test
    public void testGetIntentFromBackupTransport_WithIntent() throws Exception {
        Intent intent = mock(Intent.class);

        when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent);

        Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettings();

        assertThat(backupIntent).isEqualTo(intent);
    }

    @Test
    public void testGetIntentFromBackupTransport_WithNullIntent() throws Exception {
        when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(null);

        Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettings();

        assertThat(backupIntent).isNull();
    }

    @Test
    public void testGetIntentFromBackupTransport_RemoteException() throws Exception {
        when(mBackupManager.getDataManagementIntent(anyString())).thenThrow(new RemoteException());

        Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettings();

        assertThat(backupIntent).isNull();
    }

    @Test
    public void testGetIntentFromBackupTransport_BackupEnabled() throws Exception {
        Intent intent = new Intent("test_intent");

        when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent);
        when(mBackupManager.isBackupServiceActive(anyInt())).thenReturn(true);

        Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettings();

        assertThat(backupIntent.getExtras().get(BackupManager.EXTRA_BACKUP_SERVICES_AVAILABLE))
                .isEqualTo(true);
    }

    @Test
    public void testGetIntentFromBackupTransport_BackupDisabled() throws Exception {
        Intent intent = new Intent("test_intent");

        when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent);
        when(mBackupManager.isBackupServiceActive(anyInt())).thenReturn(false);

        Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettings();

        assertThat(backupIntent.getExtras().get(BackupManager.EXTRA_BACKUP_SERVICES_AVAILABLE))
                .isEqualTo(false);
    }

    @Test
    public void testGetIntentFromBackupTransport_BackupStatusException() throws Exception {
        Intent intent = new Intent("test_intent");

        when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent);
        when(mBackupManager.isBackupServiceActive(anyInt())).thenThrow(new RemoteException());

        Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettings();

        assertThat(backupIntent.getExtras().get(BackupManager.EXTRA_BACKUP_SERVICES_AVAILABLE))
                .isEqualTo(false);
    }

    @Test
    public void testIsIntentProvidedByTransport_WithNullIntent() throws Exception {
        when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(null);

        PackageManager packageManager = mock(PackageManager.class);

        boolean isIntentProvided = mBackupSettingsHelper.isIntentProvidedByTransport(packageManager);

        assertThat(isIntentProvided).isFalse();
    }

    @Test
    public void testIsIntentProvidedByTransport_WithInvalidIntent() throws Exception {
        Intent intent = mock(Intent.class);

        when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent);

        PackageManager packageManager = mock(PackageManager.class);
        when(intent.resolveActivity(packageManager)).thenReturn(null);

        boolean isIntentProvided = mBackupSettingsHelper.isIntentProvidedByTransport(packageManager);

        assertThat(isIntentProvided).isFalse();
    }

    @Test
    public void testIsIntentProvidedByTransport_WithIntent() throws Exception {
        Intent intent = mock(Intent.class);

        when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent);

        PackageManager packageManager = mock(PackageManager.class);
        when(intent.resolveActivity(packageManager)).thenReturn(mock(ComponentName.class));

        boolean isIntentProvided = mBackupSettingsHelper.isIntentProvidedByTransport(packageManager);

        assertThat(isIntentProvided).isTrue();
    }

    @Implements(IBackupManager.Stub.class)
    public static class ShadowBackupManagerStub {
        @Implementation
        public static IBackupManager asInterface(IBinder iBinder) {
            return mBackupManager;
        }
    }
}