1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package org.chromium.android_webview;
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import android.content.res.Resources;
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import android.util.SparseArray;
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.chromium.base.CalledByNative;
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.chromium.base.JNINamespace;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.io.IOException;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.io.InputStreamReader;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.lang.ref.SoftReference;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.util.NoSuchElementException;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.util.Scanner;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/**
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * A class that defines a set of resource IDs and functionality to resolve
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * those IDs to concrete resources.
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@JNINamespace("android_webview::AwResource")
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public class AwResource {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The following resource ID's must be initialized by the embedder.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Raw resource ID for an HTML page to be displayed in the case of
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // a specific load error.
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    private static int sRawLoadError;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Raw resource ID for an HTML page to be displayed in the case of
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // a generic load error. (It's called NO_DOMAIN for legacy reasons).
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    private static int sRawNoDomain;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Array resource ID for the configuration of platform specific key-systems.
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    private static int sStringArrayConfigKeySystemUUIDMapping;
376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The embedder should inject a Resources object that will be used
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to resolve Resource IDs into the actual resources.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static Resources sResources;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Loading some resources is expensive, so cache the results.
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    private static SparseArray<SoftReference<String>> sResourceCache;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int TYPE_STRING = 0;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int TYPE_RAW = 1;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public static void setResources(Resources resources) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sResources = resources;
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        sResourceCache = new SparseArray<SoftReference<String>>();
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    public static void setErrorPageResources(int loaderror, int nodomain) {
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        sRawLoadError = loaderror;
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        sRawNoDomain = nodomain;
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    public static void setConfigKeySystemUuidMapping(int config) {
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        sStringArrayConfigKeySystemUUIDMapping = config;
606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @CalledByNative
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public static String getNoDomainPageContent() {
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return getResource(sRawNoDomain, TYPE_RAW);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @CalledByNative
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public static String getLoadErrorPageContent() {
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return getResource(sRawLoadError, TYPE_RAW);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    public static String[] getConfigKeySystemUuidMapping() {
736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        // No need to cache, since this should be called only once.
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return sResources.getStringArray(sStringArrayConfigKeySystemUUIDMapping);
756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static String getResource(int resid, int type) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assert resid != 0;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assert sResources != null;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assert sResourceCache != null;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        SoftReference<String> stringRef = sResourceCache.get(resid);
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        String result = stringRef == null ? null : stringRef.get();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (result == null) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            switch (type) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case TYPE_STRING:
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    result = sResources.getString(resid);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case TYPE_RAW:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    result = getRawFileResourceContent(resid);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                default:
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    throw new IllegalArgumentException("Unknown resource type");
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sResourceCache.put(resid, new SoftReference<String>(result));
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return result;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static String getRawFileResourceContent(int resid) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assert resid != 0;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assert sResources != null;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        InputStreamReader isr = null;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        String result = null;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        try {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            isr = new InputStreamReader(
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    sResources.openRawResource(resid));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // \A tells the scanner to use the beginning of the input
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // as the delimiter, hence causes it to read the entire text.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            result = new Scanner(isr).useDelimiter("\\A").next();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } catch (Resources.NotFoundException e) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return "";
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } catch (NoSuchElementException e) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return "";
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        } finally {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            try {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (isr != null) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    isr.close();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            } catch (IOException e) {
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                // Nothing to do if close() fails.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return result;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
130