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

Commit 57cc87cf authored by Tony Mantler's avatar Tony Mantler
Browse files

Add TV UI for uninstalling apps

Change-Id: Ia2bf80412c5bdea12ff1051a59358877d1988ff6
parent 3da1b871
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.pm.IPackageDeleteObserver2;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
@@ -38,6 +39,8 @@ import android.util.Log;

import com.android.packageinstaller.handheld.AppNotFoundDialogFragment;
import com.android.packageinstaller.handheld.UninstallAlertDialogFragment;
import com.android.packageinstaller.television.AppNotFoundFragment;
import com.android.packageinstaller.television.UninstallAlertFragment;

/*
 * This activity presents UI to uninstall an application. Usually launched with intent
@@ -125,12 +128,31 @@ public class UninstallerActivity extends Activity {
    }

    private void showConfirmationDialog() {
        if (isTv()) {
            showContentFragment(new UninstallAlertFragment());
        } else {
            showDialogFragment(new UninstallAlertDialogFragment());
        }
    }

    private void showAppNotFound() {
        if (isTv()) {
            showContentFragment(new AppNotFoundFragment());
        } else {
            showDialogFragment(new AppNotFoundDialogFragment());
        }
    }

    private boolean isTv() {
        return (getResources().getConfiguration().uiMode & Configuration.UI_MODE_TYPE_MASK)
                == Configuration.UI_MODE_TYPE_TELEVISION;
    }

    private void showContentFragment(Fragment fragment) {
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, fragment)
                .commit();
    }

    private void showDialogFragment(DialogFragment fragment) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
+61 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.packageinstaller.television;

import android.app.Activity;
import android.os.Bundle;
import android.support.v17.leanback.app.GuidedStepFragment;
import android.support.v17.leanback.widget.GuidanceStylist;
import android.support.v17.leanback.widget.GuidedAction;

import com.android.packageinstaller.R;
import com.android.packageinstaller.UninstallerActivity;

import java.util.List;

public class AppNotFoundFragment extends GuidedStepFragment {

    @Override
    public int onProvideTheme() {
        return R.style.Theme_Leanback_GuidedStep;
    }

    @Override
    public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
        return new GuidanceStylist.Guidance(
                getString(R.string.app_not_found_dlg_title),
                getString(R.string.app_not_found_dlg_text),
                null,
                null);
    }

    @Override
    public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
        actions.add(new GuidedAction.Builder(getContext())
                .clickAction(GuidedAction.ACTION_ID_OK)
                .build());
    }

    @Override
    public void onGuidedActionClicked(GuidedAction action) {
        if (isAdded()) {
            ((UninstallerActivity) getActivity()).dispatchAborted();
            getActivity().setResult(Activity.RESULT_FIRST_USER);
            getActivity().finish();
        }
    }
}
+121 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.packageinstaller.television;

import android.app.Activity;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.os.Bundle;
import android.os.UserManager;
import android.support.v17.leanback.app.GuidedStepFragment;
import android.support.v17.leanback.widget.GuidanceStylist;
import android.support.v17.leanback.widget.GuidedAction;

import com.android.packageinstaller.R;
import com.android.packageinstaller.UninstallerActivity;

import java.util.List;

public class UninstallAlertFragment extends GuidedStepFragment {
    @Override
    public int onProvideTheme() {
        return R.style.Theme_Leanback_GuidedStep;
    }

    @Override
    public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
        final PackageManager pm = getActivity().getPackageManager();
        final UninstallerActivity.DialogInfo dialogInfo =
                ((UninstallerActivity) getActivity()).getDialogInfo();
        final CharSequence appLabel = dialogInfo.appInfo.loadLabel(pm);

        StringBuilder messageBuilder = new StringBuilder();

        // If the Activity label differs from the App label, then make sure the user
        // knows the Activity belongs to the App being uninstalled.
        if (dialogInfo.activityInfo != null) {
            final CharSequence activityLabel = dialogInfo.activityInfo.loadLabel(pm);
            if (!activityLabel.equals(appLabel)) {
                messageBuilder.append(
                        getString(R.string.uninstall_activity_text, activityLabel));
                messageBuilder.append(" ").append(appLabel).append(".\n\n");
            }
        }

        final boolean isUpdate =
                ((dialogInfo.appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
        UserManager userManager = UserManager.get(getActivity());
        if (isUpdate) {
            if (isSingleUser(userManager)) {
                messageBuilder.append(getString(R.string.uninstall_update_text));
            } else {
                messageBuilder.append(getString(R.string.uninstall_update_text_multiuser));
            }
        } else {
            if (dialogInfo.allUsers && !isSingleUser(userManager)) {
                messageBuilder.append(getString(R.string.uninstall_application_text_all_users));
            } else if (!dialogInfo.user.equals(android.os.Process.myUserHandle())) {
                UserInfo userInfo = userManager.getUserInfo(dialogInfo.user.getIdentifier());
                messageBuilder.append(
                        getString(R.string.uninstall_application_text_user, userInfo.name));
            } else {
                messageBuilder.append(getString(R.string.uninstall_application_text));
            }
        }

        return new GuidanceStylist.Guidance(
                appLabel.toString(),
                messageBuilder.toString(),
                null,
                dialogInfo.appInfo.loadIcon(pm));
    }

    @Override
    public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
        actions.add(new GuidedAction.Builder(getContext())
                .clickAction(GuidedAction.ACTION_ID_OK)
                .build());
        actions.add(new GuidedAction.Builder(getContext())
                .clickAction(GuidedAction.ACTION_ID_CANCEL)
                .build());
    }

    @Override
    public void onGuidedActionClicked(GuidedAction action) {
        if (isAdded()) {
            if (action.getId() == GuidedAction.ACTION_ID_OK) {
                ((UninstallerActivity) getActivity()).startUninstallProgress();
                getActivity().finish();
            } else {
                ((UninstallerActivity) getActivity()).dispatchAborted();
                getActivity().setResult(Activity.RESULT_FIRST_USER);
                getActivity().finish();
            }
        }
    }

    /**
     * Returns whether there is only one user on this device, not including
     * the system-only user.
     */
    private boolean isSingleUser(UserManager userManager) {
        final int userCount = userManager.getUserCount();
        return userCount == 1
                || (UserManager.isSplitSystemUser() && userCount == 2);
    }
}