172e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov/*
272e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project
372e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov *
472e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License");
572e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * you may not use this file except in compliance with the License.
672e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * You may obtain a copy of the License at
772e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov *
872e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov *      http://www.apache.org/licenses/LICENSE-2.0
972e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov *
1072e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * Unless required by applicable law or agreed to in writing, software
1172e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS,
1272e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1372e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * See the License for the specific language governing permissions and
1472e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * limitations under the License.
1572e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov */
1672e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikovpackage com.android.providers.contacts;
1772e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov
1872e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikovimport android.content.Context;
1972e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikovimport android.content.pm.ApplicationInfo;
2072e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikovimport android.content.pm.PackageInfo;
2172e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikovimport android.content.pm.PackageManager;
22ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onukiimport android.content.pm.ProviderInfo;
23e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikovimport android.content.res.Resources;
2472e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikovimport android.os.Binder;
2572e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikovimport android.test.mock.MockPackageManager;
2672e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov
2738210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.google.android.collect.Lists;
2838210445730ee04c351c7cc1b3800cfe23e34325Makoto Onuki
2972e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikovimport java.util.HashMap;
3072e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikovimport java.util.List;
3172e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov
3272e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov/**
3372e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * Mock {@link PackageManager} that knows about a specific set of packages
3472e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * to help test security models. Because {@link Binder#getCallingUid()}
3572e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * can't be mocked, you'll have to find your mock-UID manually using your
3672e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov * {@link Context#getPackageName()}.
3772e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov */
3872e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikovpublic class ContactsMockPackageManager extends MockPackageManager {
3972e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    private final HashMap<Integer, String> mForward = new HashMap<Integer, String>();
4072e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    private final HashMap<String, Integer> mReverse = new HashMap<String, Integer>();
4172e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    private List<PackageInfo> mPackages;
4272e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov
4372e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    public ContactsMockPackageManager() {
4472e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    }
4572e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov
4672e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    /**
4772e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov     * Add a UID-to-package mapping, which is then stored internally.
4872e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov     */
4972e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    public void addPackage(int packageUid, String packageName) {
5072e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        mForward.put(packageUid, packageName);
5172e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        mReverse.put(packageName, packageUid);
5272e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    }
5372e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov
5472e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    @Override
5572e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    public String getNameForUid(int uid) {
5672e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        return "name-for-uid";
5772e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    }
5872e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov
5972e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    @Override
6072e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    public String[] getPackagesForUid(int uid) {
6172e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        if (mPackages != null) {
6272e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov            return new String[] { mPackages.get(0).packageName };
6372e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        } else {
6472e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov            return new String[] { ContactsActor.sCallingPackage };
6572e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        }
6672e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    }
6772e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov
6872e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    @Override
6972e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    public ApplicationInfo getApplicationInfo(String packageName, int flags) {
7072e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        ApplicationInfo info = new ApplicationInfo();
7172e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        Integer uid = mReverse.get(packageName);
7272e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        info.uid = (uid != null) ? uid : -1;
7372e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        return info;
7472e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    }
7572e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov
7672e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    public void setInstalledPackages(List<PackageInfo> packages) {
7772e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        this.mPackages = packages;
7872e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    }
7972e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov
8072e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    @Override
8172e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    public List<PackageInfo> getInstalledPackages(int flags) {
8272e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        return mPackages;
8372e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    }
8472e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov
8572e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    @Override
8672e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException {
8772e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        for (PackageInfo info : mPackages) {
8872e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov            if (info.packageName.equals(packageName)) {
8972e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov                return info;
9072e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov            }
9172e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        }
9272e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        throw new NameNotFoundException();
9372e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov    }
94e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov
95e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov    @Override
96e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov    public Resources getResourcesForApplication(String appPackageName) {
970bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        return new ContactsMockResources();
98e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov    }
99ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki
100ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki    @Override
101ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki    public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
102ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki        final List<ProviderInfo> ret = Lists.newArrayList();
103ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki        if (mPackages == null) return ret;
104ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki        for (PackageInfo packageInfo : mPackages) {
105ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki            if (packageInfo.providers == null) continue;
106ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki            for (ProviderInfo providerInfo : packageInfo.providers) {
107ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki                ret.add(providerInfo);
108ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki            }
109ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki        }
110ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki        return ret;
111ac6f0b8a92fccb3611a7841d0f04e4ac24a58c91Makoto Onuki    }
11272e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov}
113