1 /* 2 * Copyright (C) 2015 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.tv.settings.device.storage; 18 19 import android.content.pm.ApplicationInfo; 20 import android.content.pm.PackageManager; 21 import android.graphics.drawable.Drawable; 22 import android.os.Bundle; 23 import android.os.storage.StorageManager; 24 import android.os.storage.VolumeInfo; 25 import android.support.annotation.NonNull; 26 import android.support.v17.leanback.app.GuidedStepFragment; 27 import android.support.v17.leanback.widget.GuidanceStylist; 28 import android.support.v17.leanback.widget.GuidedAction; 29 import android.text.TextUtils; 30 import android.text.format.Formatter; 31 import android.util.Log; 32 33 import com.android.tv.settings.R; 34 35 import java.io.File; 36 import java.util.List; 37 38 public class MoveAppStepFragment extends GuidedStepFragment { 39 40 private static final String TAG = "MoveAppStepFragment"; 41 42 private static final String ARG_PACKAGE_NAME = "packageName"; 43 private static final String ARG_PACKAGE_DESC = "packageDesc"; 44 45 private PackageManager mPackageManager; 46 private StorageManager mStorageManager; 47 48 private String mPackageName; 49 private String mPackageDesc; 50 private List<VolumeInfo> mCandidateVolumes; 51 private VolumeInfo mCurrentVolume; 52 53 public interface Callback { 54 void onRequestMovePackageToVolume(String packageName, VolumeInfo destination); 55 } 56 57 public static MoveAppStepFragment newInstance(String packageName, String packageDesc) { 58 final MoveAppStepFragment fragment = new MoveAppStepFragment(); 59 final Bundle b = new Bundle(2); 60 b.putString(ARG_PACKAGE_NAME, packageName); 61 b.putString(ARG_PACKAGE_DESC, packageDesc); 62 fragment.setArguments(b); 63 return fragment; 64 } 65 66 @Override 67 public void onCreate(Bundle savedInstanceState) { 68 // Need mPackageManager before onCreateActions, which is called from super.onCreate 69 mPackageManager = getActivity().getPackageManager(); 70 mStorageManager = getActivity().getSystemService(StorageManager.class); 71 72 mPackageDesc = getArguments().getString(ARG_PACKAGE_DESC, ""); 73 mPackageName = getArguments().getString(ARG_PACKAGE_NAME); 74 75 super.onCreate(savedInstanceState); 76 } 77 78 @Override 79 public void onResume() { 80 super.onResume(); 81 } 82 83 @Override 84 public @NonNull GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { 85 Drawable icon; 86 try { 87 icon = mPackageManager.getApplicationIcon(mPackageName); 88 } catch (PackageManager.NameNotFoundException e) { 89 Log.d(TAG, "Missing package while resolving icon", e); 90 icon = null; 91 } 92 return new GuidanceStylist.Guidance(getString(R.string.storage_wizard_move_app_title), 93 null, 94 mPackageDesc, 95 icon); 96 } 97 98 @Override 99 public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) { 100 final String packageName = getArguments().getString(ARG_PACKAGE_NAME); 101 final ApplicationInfo info; 102 try { 103 info = mPackageManager.getApplicationInfo(packageName, 0); 104 } catch (PackageManager.NameNotFoundException e) { 105 Log.d(TAG, "Package missing while resolving storage", e); 106 return; 107 } 108 mCurrentVolume = mPackageManager.getPackageCurrentVolume(info); 109 mCandidateVolumes = mPackageManager.getPackageCandidateVolumes(info); 110 111 for (final VolumeInfo candidate : mCandidateVolumes) { 112 if (!candidate.isMountedWritable()) { 113 continue; 114 } 115 final File path = candidate.getPath(); 116 final String avail = Formatter.formatFileSize(getActivity(), path.getFreeSpace()); 117 actions.add(new GuidedAction.Builder(getContext()) 118 .title(mStorageManager.getBestVolumeDescription(candidate)) 119 .description( 120 getString(R.string.storage_wizard_back_up_apps_space_available, avail)) 121 .checked(TextUtils.equals(mCurrentVolume.getId(), candidate.getId())) 122 .checkSetId(GuidedAction.DEFAULT_CHECK_SET_ID) 123 .id(mCandidateVolumes.indexOf(candidate)) 124 .build()); 125 } 126 } 127 128 @Override 129 public void onGuidedActionClicked(GuidedAction action) { 130 final Callback callback = (Callback) getActivity(); 131 final VolumeInfo destination = mCandidateVolumes.get((int) action.getId()); 132 if (destination.equals(mCurrentVolume)) { 133 if (!getFragmentManager().popBackStackImmediate()) { 134 getActivity().finish(); 135 } 136 } else { 137 callback.onRequestMovePackageToVolume(mPackageName, destination); 138 } 139 } 140 141 } 142