1a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer/*
2a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer * Copyright (C) 2011 The Android Open Source Project
3a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer *
4a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer * Licensed under the Apache License, Version 2.0 (the "License");
5a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer * you may not use this file except in compliance with the License.
6a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer * You may obtain a copy of the License at
7a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer *
8a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer *      http://www.apache.org/licenses/LICENSE-2.0
9a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer *
10a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer * Unless required by applicable law or agreed to in writing, software
11a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer * distributed under the License is distributed on an "AS IS" BASIS,
12a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer * See the License for the specific language governing permissions and
14a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer * limitations under the License.
15a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer */
16a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer
17a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmerpackage android.content.pm;
18a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer
19199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chenimport android.content.Context;
20a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmerimport android.os.IBinder;
21a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmerimport android.os.RemoteException;
22a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmerimport android.os.ServiceManager;
232250d56a0b47b93016018340c8f4040325aa5611Sudheer Shankaimport android.os.storage.IStorageManager;
24199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chenimport android.os.storage.StorageManager;
25199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chenimport android.os.storage.VolumeInfo;
26a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmerimport android.test.AndroidTestCase;
27a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmerimport android.util.Log;
28a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer
29941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkeyimport com.android.internal.content.PackageHelper;
30941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey
31199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chenimport org.mockito.Mockito;
32199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
33199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chenimport java.io.File;
34199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chenimport java.io.IOException;
35199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chenimport java.util.ArrayList;
36199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chenimport java.util.List;
374233f032fd41e82d1ce09b48860f8ae3f73fa5e0Jeff Sharkeyimport java.util.UUID;
38199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
39199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chenimport static android.net.TrafficStats.MB_IN_BYTES;
40199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chenimport static android.os.storage.VolumeInfo.STATE_MOUNTED;
41199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
42a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmerpublic class PackageHelperTests extends AndroidTestCase {
43a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    private static final boolean localLOGV = true;
44a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    public static final String TAG = "PackageHelperTests";
45a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    protected final String PREFIX = "android.content.pm";
462250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka    private IStorageManager mSm;
47a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    private String fullId;
48a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    private String fullId2;
49a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer
50199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    private static final String sInternalVolPath = "/data";
51199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    private static final String sAdoptedVolPath = "/mnt/expand/123";
52199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    private static final String sPublicVolPath = "/emulated";
53199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
54199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    private static final String sInternalVolUuid = StorageManager.UUID_PRIVATE_INTERNAL;
55199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    private static final String sAdoptedVolUuid = "adopted";
56199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    private static final String sPublicVolUuid = "emulated";
57199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
58199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    private static final long sInternalSize = 20000;
59199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    private static final long sAdoptedSize = 10000;
60199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    private static final long sPublicSize = 1000000;
61199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
62683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey    private static StorageManager sStorageManager;
63199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
64683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey    private static StorageManager createStorageManagerMock() throws Exception {
65199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        VolumeInfo internalVol = new VolumeInfo("private",
66199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                VolumeInfo.TYPE_PRIVATE, null /*DiskInfo*/, null /*partGuid*/);
67199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        internalVol.path = sInternalVolPath;
68199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        internalVol.state = STATE_MOUNTED;
69199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        internalVol.fsUuid = sInternalVolUuid;
70199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
71199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        VolumeInfo adoptedVol = new VolumeInfo("adopted",
72199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                VolumeInfo.TYPE_PRIVATE, null /*DiskInfo*/, null /*partGuid*/);
73199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        adoptedVol.path = sAdoptedVolPath;
74199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        adoptedVol.state = STATE_MOUNTED;
75199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        adoptedVol.fsUuid = sAdoptedVolUuid;
76199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
77199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        VolumeInfo publicVol = new VolumeInfo("public",
78199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                VolumeInfo.TYPE_PUBLIC, null /*DiskInfo*/, null /*partGuid*/);
79199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        publicVol.state = STATE_MOUNTED;
80199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        publicVol.path = sPublicVolPath;
81199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        publicVol.fsUuid = sPublicVolUuid;
82199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
83199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        List<VolumeInfo> volumes = new ArrayList<>();
84199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volumes.add(internalVol);
85199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volumes.add(adoptedVol);
86199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volumes.add(publicVol);
87199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
88199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        StorageManager storageManager = Mockito.mock(StorageManager.class);
89199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        Mockito.when(storageManager.getVolumes()).thenReturn(volumes);
90199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
91199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        File internalFile = new File(sInternalVolPath);
92199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        File adoptedFile = new File(sAdoptedVolPath);
93199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        File publicFile = new File(sPublicVolPath);
944233f032fd41e82d1ce09b48860f8ae3f73fa5e0Jeff Sharkey        UUID internalUuid = UUID.randomUUID();
954233f032fd41e82d1ce09b48860f8ae3f73fa5e0Jeff Sharkey        UUID adoptedUuid = UUID.randomUUID();
964233f032fd41e82d1ce09b48860f8ae3f73fa5e0Jeff Sharkey        UUID publicUuid = UUID.randomUUID();
97199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        Mockito.when(storageManager.getStorageBytesUntilLow(internalFile)).thenReturn(sInternalSize);
98199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        Mockito.when(storageManager.getStorageBytesUntilLow(adoptedFile)).thenReturn(sAdoptedSize);
99199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        Mockito.when(storageManager.getStorageBytesUntilLow(publicFile)).thenReturn(sPublicSize);
1004233f032fd41e82d1ce09b48860f8ae3f73fa5e0Jeff Sharkey        Mockito.when(storageManager.getUuidForPath(Mockito.eq(internalFile))).thenReturn(internalUuid);
1014233f032fd41e82d1ce09b48860f8ae3f73fa5e0Jeff Sharkey        Mockito.when(storageManager.getUuidForPath(Mockito.eq(adoptedFile))).thenReturn(adoptedUuid);
1024233f032fd41e82d1ce09b48860f8ae3f73fa5e0Jeff Sharkey        Mockito.when(storageManager.getUuidForPath(Mockito.eq(publicFile))).thenReturn(publicUuid);
1034233f032fd41e82d1ce09b48860f8ae3f73fa5e0Jeff Sharkey        Mockito.when(storageManager.getAllocatableBytes(Mockito.eq(internalUuid), Mockito.anyInt()))
104683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey                .thenReturn(sInternalSize);
1054233f032fd41e82d1ce09b48860f8ae3f73fa5e0Jeff Sharkey        Mockito.when(storageManager.getAllocatableBytes(Mockito.eq(adoptedUuid), Mockito.anyInt()))
106683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey                .thenReturn(sAdoptedSize);
1074233f032fd41e82d1ce09b48860f8ae3f73fa5e0Jeff Sharkey        Mockito.when(storageManager.getAllocatableBytes(Mockito.eq(publicUuid), Mockito.anyInt()))
108683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey                .thenReturn(sPublicSize);
109199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        return storageManager;
110199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    }
111199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
112199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    private static final class MockedInterface extends PackageHelper.TestableInterface {
113199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        private boolean mForceAllowOnExternal = false;
114199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        private boolean mAllow3rdPartyOnInternal = true;
115199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        private ApplicationInfo mApplicationInfo = null;
116199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
117199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        public void setMockValues(ApplicationInfo applicationInfo,
118199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                boolean forceAllowOnExternal, boolean allow3rdPartyOnInternal) {
119199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            mForceAllowOnExternal = forceAllowOnExternal;
120199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            mAllow3rdPartyOnInternal = allow3rdPartyOnInternal;
121199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            mApplicationInfo = applicationInfo;
122199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
123199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
124199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        @Override
125199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        public StorageManager getStorageManager(Context context) {
126199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            return sStorageManager;
127199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
128199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
129199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        @Override
130199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        public boolean getForceAllowOnExternalSetting(Context context) {
131199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            return mForceAllowOnExternal;
132199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
133199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
134199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        @Override
135199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        public boolean getAllow3rdPartyOnInternalConfig(Context context) {
136199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            return mAllow3rdPartyOnInternal;
137199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
138199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
139199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        @Override
140199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        public ApplicationInfo getExistingAppInfo(Context context, String packagename) {
141199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            return mApplicationInfo;
142199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
143199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
144199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        @Override
145199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        public File getDataDirectory() {
146199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            return new File(sInternalVolPath);
147199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
148199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    }
149199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
1502250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka    private IStorageManager getSm() {
151a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        IBinder service = ServiceManager.getService("mount");
152a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        if (service != null) {
1532250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka            return IStorageManager.Stub.asInterface(service);
154a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        } else {
155a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer            Log.e(TAG, "Can't get mount service");
156a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        }
157a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        return null;
158a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    }
159a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer
160a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    private void cleanupContainers() throws RemoteException {
161a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        Log.d(TAG,"cleanUp");
1622250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka        IStorageManager sm = getSm();
1632250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka        String[] containers = sm.getSecureContainerList();
164a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        for (int i = 0; i < containers.length; i++) {
165a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer            if (containers[i].startsWith(PREFIX)) {
166a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                Log.d(TAG,"cleaing up "+containers[i]);
1672250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka                sm.destroySecureContainer(containers[i], true);
168a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer            }
169a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        }
170a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    }
171a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer
172a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    @Override
173a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    protected void setUp() throws Exception {
174a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        super.setUp();
175683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        sStorageManager = createStorageManagerMock();
176a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        if (localLOGV) Log.i(TAG, "Cleaning out old test containers");
177a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        cleanupContainers();
178a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    }
179a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer
180a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    @Override
181a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    protected void tearDown() throws Exception {
182a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        super.tearDown();
183683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        sStorageManager = null;
184a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        if (localLOGV) Log.i(TAG, "Cleaning out old test containers");
185a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        cleanupContainers();
186a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    }
187a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer
188683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey    public void testMountAndPullSdCard() throws Exception {
189683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        fullId = PREFIX;
190683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        fullId2 = PackageHelper.createSdDir(1024 * MB_IN_BYTES, fullId, "none",
191683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey                android.os.Process.myUid(), true);
192683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey
193683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        Log.d(TAG, "getSdDir=" + PackageHelper.getSdDir(fullId));
194683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        PackageHelper.unMountSdDir(fullId);
195683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey
196683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        Runnable r1 = getMountRunnable();
197683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        Runnable r2 = getDestroyRunnable();
198683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        Thread thread = new Thread(r1);
199683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        Thread thread2 = new Thread(r2);
200683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        thread2.start();
201683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        thread.start();
202a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    }
203a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer
204a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    public Runnable getMountRunnable() {
205a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        Runnable r = new Runnable () {
206a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer            public void run () {
207a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                try {
208a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                    Thread.sleep(5);
209a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                    String path = PackageHelper.mountSdDir(fullId, "none",
210a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                            android.os.Process.myUid());
211a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                    Log.e(TAG, "mount done " + path);
212a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                } catch (IllegalArgumentException iae) {
213a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                    throw iae;
214a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                } catch (Throwable t) {
215a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                    Log.e(TAG, "mount failed", t);
216a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                }
217a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer            }
218a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        };
219a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        return r;
220a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    }
221a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer
222a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    public Runnable getDestroyRunnable() {
223a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        Runnable r = new Runnable () {
224a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer            public void run () {
225a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                try {
226a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                    PackageHelper.destroySdDir(fullId);
227a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                    Log.e(TAG, "destroy done: " + fullId);
228a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                } catch (Throwable t) {
229a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                    Log.e(TAG, "destroy failed", t);
230a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer                }
231a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer            }
232a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        };
233a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer        return r;
234a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer    }
235199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
236199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    public void testResolveInstallVolumeInternal_SystemApp() throws IOException {
237199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        ApplicationInfo systemAppInfo = new ApplicationInfo();
238199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        systemAppInfo.flags = ApplicationInfo.FLAG_SYSTEM;
239199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
240199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // All test cases for when the system app fits on internal.
241199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        MockedInterface mockedInterface = new MockedInterface();
242199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(systemAppInfo, false /*force allow on external*/,
243199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
244199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        String volume = null;
245199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
246199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            1 /*install location*/, 1000 /*size bytes*/, mockedInterface);
247199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(StorageManager.UUID_PRIVATE_INTERNAL, volume);
248199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
249199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(systemAppInfo, true /*force allow on external*/,
250199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
251199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
252199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                1 /*install location*/, 1000 /*size bytes*/, mockedInterface);
253199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(StorageManager.UUID_PRIVATE_INTERNAL, volume);
254199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
255199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(systemAppInfo, false /*force allow on external*/,
256199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
257199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
258199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                1 /*install location*/, 1000 /*size bytes*/, mockedInterface);
259199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(StorageManager.UUID_PRIVATE_INTERNAL, volume);
260199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
261199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(systemAppInfo, true /*force allow on external*/,
262199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
263199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
264199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                1 /*install location*/, 1000 /*size bytes*/, mockedInterface);
265199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(StorageManager.UUID_PRIVATE_INTERNAL, volume);
266199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
267199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
268199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // All test cases for when the system app does not fit on internal.
269199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Exception should be thrown.
270199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(systemAppInfo, true /*force allow on external*/,
271199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
272199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        try {
273199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            PackageHelper.resolveInstallVolume(getContext(), "package.name",
274199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                    1 /*install location*/, 1000000 /*size bytes*/, mockedInterface);
275199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            fail("Expected exception in resolveInstallVolume was not thrown");
276199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        } catch(IOException e) {
277199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            // expected
278199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
279199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
280199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(systemAppInfo, false /*force allow on external*/,
281199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
282199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        try {
283199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            PackageHelper.resolveInstallVolume(getContext(), "package.name",
284199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                    1 /*install location*/, 1000000 /*size bytes*/, mockedInterface);
285199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            fail("Expected exception in resolveInstallVolume was not thrown");
286199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        } catch(IOException e) {
287199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            // expected
288199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
289199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
290199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(systemAppInfo, false /*force allow on external*/,
291199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
292199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        try {
293199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            PackageHelper.resolveInstallVolume(getContext(), "package.name",
294199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                    1 /*install location*/, 1000000 /*size bytes*/, mockedInterface);
295199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            fail("Expected exception in resolveInstallVolume was not thrown");
296199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        } catch(IOException e) {
297199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            // expected
298199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
299199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
300199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(systemAppInfo, true /*force allow on external*/,
301199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
302199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        try {
303199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            PackageHelper.resolveInstallVolume(getContext(), "package.name",
304199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                    1 /*install location*/, 1000000 /*size bytes*/, mockedInterface);
305199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            fail("Expected exception in resolveInstallVolume was not thrown");
306199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        } catch(IOException e) {
307199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            // expected
308199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
309199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    }
310199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
311199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    public void testResolveInstallVolumeInternal_3rdParty_existing_not_too_big()
312199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            throws IOException {
313199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Existing apps always stay on the same volume.
314199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Test cases for existing app on internal.
315199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        ApplicationInfo appInfo = new ApplicationInfo();
316199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        appInfo.volumeUuid = sInternalVolUuid;
317199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        MockedInterface mockedInterface = new MockedInterface();
318199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, false /*force allow on external*/,
319199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
320199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        String volume = null;
321199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
322199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                0 /*install location*/, 1000 /*size bytes*/, mockedInterface);
323199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sInternalVolUuid, volume);
324199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
325199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, true /*force allow on external*/,
326199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
327199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
328199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                0 /*install location*/, 1000 /*size bytes*/, mockedInterface);
329199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sInternalVolUuid, volume);
330199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    }
331199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
332199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    public void testResolveInstallVolumeInternal_3rdParty_existing_not_too_big_adopted()
333199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            throws IOException {
334199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Test cases for existing app on the adopted media.
335199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        ApplicationInfo appInfo = new ApplicationInfo();
336199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        MockedInterface mockedInterface = new MockedInterface();
337199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        String volume;
338199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        appInfo.volumeUuid = sAdoptedVolUuid;
339199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, false /*force allow on external*/,
340199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
341199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
342199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            0 /*install location*/, 1000 /*size bytes*/, mockedInterface);
343199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sAdoptedVolUuid, volume);
344199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
345199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, true /*force allow on external*/,
346199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
347199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
348199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                0 /*install location*/, 1000 /*size bytes*/, mockedInterface);
349199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sAdoptedVolUuid, volume);
350199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
351199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, false /*force allow on external*/,
352199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
353199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
354199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                0 /*install location*/, 1000 /*size bytes*/, mockedInterface);
355199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sAdoptedVolUuid, volume);
356199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
357199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, true /*force allow on external*/,
358199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
359199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
360199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                0 /*install location*/, 1000 /*size bytes*/, mockedInterface);
361199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sAdoptedVolUuid, volume);
362199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    }
363199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
364199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    public void testResolveInstallVolumeAdopted_3rdParty_existing_too_big() {
365199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Test: update size too big, will throw exception.
366199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        ApplicationInfo appInfo = new ApplicationInfo();
367199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        appInfo.volumeUuid = sAdoptedVolUuid;
368199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
369199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        MockedInterface mockedInterface = new MockedInterface();
370199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, false /*force allow on external*/,
371199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
372199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        try {
373199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            PackageHelper.resolveInstallVolume(getContext(), "package.name",
374199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                    0 /*install location*/, 10000001 /*BIG size, won't fit*/, mockedInterface);
375199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            fail("Expected exception was not thrown " + appInfo.volumeUuid);
376199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        } catch (IOException e) {
377199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            //expected
378199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
379199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
380199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, false /*force allow on external*/,
381199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
382199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        try {
383199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            PackageHelper.resolveInstallVolume(getContext(), "package.name",
384199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                    0 /*install location*/, 10000001 /*BIG size, won't fit*/, mockedInterface);
385199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            fail("Expected exception was not thrown " + appInfo.volumeUuid);
386199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        } catch (IOException e) {
387199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            //expected
388199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
389199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
390199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, true /*force allow on external*/,
391199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
392199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        try {
393199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            PackageHelper.resolveInstallVolume(getContext(), "package.name",
394199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                    0 /*install location*/, 10000001 /*BIG size, won't fit*/, mockedInterface);
395199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            fail("Expected exception was not thrown " + appInfo.volumeUuid);
396199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        } catch (IOException e) {
397199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            //expected
398199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
399199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
400199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, true /*force allow on external*/,
401199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
402199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        try {
403199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            PackageHelper.resolveInstallVolume(getContext(), "package.name",
404199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                    0 /*install location*/, 10000001 /*BIG size, won't fit*/, mockedInterface);
405199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            fail("Expected exception was not thrown " + appInfo.volumeUuid);
406199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        } catch (IOException e) {
407199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            //expected
408199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
409199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    }
410199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
411199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    public void testResolveInstallVolumeInternal_3rdParty_auto() throws IOException {
412199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        ApplicationInfo appInfo = null;
413199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        MockedInterface mockedInterface = new MockedInterface();
414199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, false /*force allow on external*/,
415199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
416199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        String volume = null;
417199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
418199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            0 /*install location auto*/, 1000 /*size bytes*/, mockedInterface);
419199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Should return the volume with bigger available space.
420199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sInternalVolUuid, volume);
421199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
422199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, true /*force allow on external*/,
423199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
424199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
425199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                0 /*install location auto*/, 1000 /*size bytes*/, mockedInterface);
426199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Should return the volume with bigger available space.
427199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sInternalVolUuid, volume);
428199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
429199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, true /*force allow on external*/,
430199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
431199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
432199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                0 /*install location auto*/, 1000 /*size bytes*/, mockedInterface);
433199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Should return the volume with bigger available space.
434199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sAdoptedVolUuid, volume);
435199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
436199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, false /*force allow on external*/,
437199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
438199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
439199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                0 /*install location auto*/, 1000 /*size bytes*/, mockedInterface);
440199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Should return the volume with bigger available space.
441199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sAdoptedVolUuid, volume);
442199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
443199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
444199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    }
445199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
446199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    public void testResolveInstallVolumeInternal_3rdParty_internal_only() throws IOException {
447199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        ApplicationInfo appInfo = null;
448199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        MockedInterface mockedInterface = new MockedInterface();
449199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, false /*force allow on external*/,
450199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
451199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        String volume = null;
452199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
453199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            1 /*install location internal ONLY*/, 1000 /*size bytes*/, mockedInterface);
454199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sInternalVolUuid, volume);
455199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
456199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, true /*force allow on external*/,
457199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
458199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
459199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                1 /*install location internal ONLY*/, 1000 /*size bytes*/, mockedInterface);
460199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sInternalVolUuid, volume);
461199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
462199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, false /*force allow on external*/,
463199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
464199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        try {
465199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
466199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                    1 /*install location internal only*/, 1000 /*size bytes*/, mockedInterface);
467199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            fail("Expected exception in resolveInstallVolume was not thrown");
468199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        } catch (IOException e) {
469199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            //expected
470199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
471199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
472199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        appInfo = null;
473199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, true /*force allow on external*/,
474199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
475199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = null;
476199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
477199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                1 /*install location internal only*/, 1000 /*size bytes*/, mockedInterface);
478199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sAdoptedVolUuid, volume);
479199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    }
480199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
481199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    public void testResolveInstallVolumeInternal_3rdParty_not_allowed_on_internal()
482199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        throws IOException {
483199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        ApplicationInfo appInfo = null;
484199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        MockedInterface mockedInterface = new MockedInterface();
485199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, false /*force allow on external*/,
486199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
487199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        String volume = null;
488199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
489199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            0 /*install location auto*/, 1000 /*size bytes*/, mockedInterface);
490199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Should return the non-internal volume.
491199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sAdoptedVolUuid, volume);
492199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
493199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        appInfo = null;
494199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, true /*force allow on external*/,
495199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
496199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
497199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                0 /*install location auto*/, 1000 /*size bytes*/, mockedInterface);
498199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Should return the non-internal volume.
499199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sAdoptedVolUuid, volume);
500199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    }
501199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
502199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    public void testResolveInstallVolumeInternal_3rdParty_internal_only_too_big() {
503199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        ApplicationInfo appInfo = null;
504199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        MockedInterface mockedInterface = new MockedInterface();
505199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, false /*force allow on external*/,
506199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                true /*allow 3rd party on internal*/);
507199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        String volume = null;
508199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        try {
509199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
510199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                    1 /*install location internal ONLY*/,
511199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                    1000000 /*size too big*/, mockedInterface);
512199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            fail("Expected exception in resolveInstallVolume was not thrown");
513199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        } catch (IOException e) {
514199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            //expected
515199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
516199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    }
517199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
518199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    public void testResolveInstallVolumeInternal_3rdParty_internal_only_not_allowed()
519199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        throws IOException {
520199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        ApplicationInfo appInfo = null;
521199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        MockedInterface mockedInterface = new MockedInterface();
522199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, false /*force allow on external*/,
523199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
524199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        String volume = null;
525199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        try {
526199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
527199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                    1 /*install location internal only*/, 1000 /*size bytes*/, mockedInterface);
528199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            fail("Expected exception in resolveInstallVolume was not thrown");
529199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        } catch (IOException e) {
530199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            //expected
531199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        }
532199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
533199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        appInfo = null;
534199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, true /*force allow on external*/,
535199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
536199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = null;
537199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
538199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            1 /*install location internal only*/, 1000 /*size bytes*/, mockedInterface);
539199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sAdoptedVolUuid, volume);
540199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
541199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    }
542199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen
543199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    public void testResolveInstallVolumeInternal_3rdParty_internal_only_forced_to_external()
544199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        throws IOException {
545199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // New/existing installation: New
546199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // app request location: Internal Only
547199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // 3rd party allowed on internal: False
548199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Force allow external in setting: True
549199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        // Size fit? Yes
550199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        ApplicationInfo appInfo = null;
551199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        MockedInterface mockedInterface = new MockedInterface();
552199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        mockedInterface.setMockValues(appInfo, true /*force allow on external*/,
553199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen                false /*allow 3rd party on internal*/);
554199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        String volume = null;
555199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        volume = PackageHelper.resolveInstallVolume(getContext(), "package.name",
556199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen            1 /*install location internal only*/, 1000 /*size bytes*/, mockedInterface);
557199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen        assertEquals(sAdoptedVolUuid, volume);
558199b5d6efdf559db32b52f4d822de1e3ed6724feYao Chen    }
559a20c8ef471666cf8b0dca91a8739ff18af1741a5Fredrik Helmer}
560